/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

// Diff -- text file difference utility.


package com.sun.ejte.ccl.filediff;

import java.io.*;
//import com.sun.ejte.ccl.reporter.*;

/** This is the info kept per-file.     */
class fileInfo {

        static final int MAXLINECOUNT = 20000;

        DataInputStream file;        /* File handle that is open for read.  */
        public int maxLine;        /* After input done, # lines in file.  */
        node symbol[]; /* The symtab handle of each line. */
        int other[]; /* Map of line# to line# in other file */
                                /* ( -1 means don't-know ).            */
                                /* Allocated AFTER the lines are read. */

        /**
         * Normal constructor with one filename; file is opened and saved.
         */
        fileInfo( String filename ) {
                symbol = new node [ MAXLINECOUNT+2 ];
                other  = null;                // allocated later!
                try {
                        file = new DataInputStream(
                                new FileInputStream( filename));
                } catch (IOException e) {
                          System.err.println("Diff can't read file " +
                                filename );
                          System.err.println("Error Exception was:" + e );
                          System.exit(1);
                }
        }
        // This is done late, to be same size as # lines in input file.
        void alloc() {
                other  = new int[symbol.length + 2];
        }
};

/**

 * USAGE:      diff oldfile newfile
 *
 * This program assumes that "oldfile" and "newfile" are text files.
 * The program writes to stdout a description of the changes which would
 * transform "oldfile" into "newfile".
 *
 * The printout is in the form of commands, each followed by a block of
 * text. The text is delimited by the commands, which are:
 *
 *    DELETE AT n
 *         ..deleted lines
 *
 *    INSERT BEFORE n
 *         ..inserted lines
 *
 *    n MOVED TO BEFORE n
 *         ..moved lines
 *
 *    n CHANGED FROM
 *         ..old lines
 *    CHANGED TO
 *         ..newer lines
 *
 * The line numbers all refer to the lines of the oldfile, as they are
 *    numbered before any commands are applied.
 * The text lines are printed as-is, without indentation or prefixing. The
 *    commands are printed in upper case, with a prefix of ">>>>", so that
 *    they will stand out. Other schemes may be preferred.
 * Files which contain more than MAXLINECOUNT lines cannot be processed.
 *    This can be fixed by changing "symbol" to a Vector.
 *    Ignoring I/O, and ignoring the symbol table, it should take O(N) time.
 *    This implementation takes fixed space, plus O(U) space for the symbol
 *    table (where U is the number of unique lines). Methods exist to change
 *    the fixed space to O(N) space.
 */
public class Diff {

        /** block len > any possible real block len */
        final int UNREAL=Integer.MAX_VALUE;

       // private static SimpleReporterAdapter stat=new SimpleReporterAdapter();

        /** Keeps track of information about file1 and file2 */
        fileInfo oldinfo, newinfo;

        /** blocklen is the info about found blocks. It will be set to 0, except
         * at the line#s where blocks start in the old file. At these places it
         * will be set to the # of lines in the block. During printout ,
         * this # will be reset to -1 if the block is printed as a MOVE block
         * (because the printout phase will encounter the block twice, but
         * must only print it once.)
         * The array declarations are to MAXLINECOUNT+2 so that we can have two
         * extra lines (pseudolines) at line# 0 and line# MAXLINECOUNT+1
         * (or less).
         */
        int blocklen[];

        /**
         * main - entry point when used standalone.
         * NOTE: no routines return error codes or throw any local
         * exceptions. Instead, any routine may complain
         * to stderr and then exit with error to the system.
         */
        public static void main(String argstrings[])
        {
                if ( argstrings.length != 2 ) {
                  System.err.println("Usage: diff oldfile newfile" );
                  System.exit(1);
                }
                Diff d = new Diff();
                d.doDiff(argstrings[0], argstrings[1]);
                return;
        }

        /** Construct a Diff object. */
        Diff() {
        }

        /** Do one file comparison. Called with both filenames. */
        public void doDiff(String oldFile, String newFile) {
                //stat.addDescription("This is test suite  for AVK");
                println( ">>>> Difference of file \"" + oldFile +
                        "\" and file \"" + newFile + "\".\n");
                oldinfo = new fileInfo(oldFile);
                newinfo = new fileInfo(newFile);
                /* we don't process until we know both files really do exist. */
                try {
                        inputscan( oldinfo );
                        inputscan( newinfo );
                } catch (IOException e) {
                        System.err.println("Read error: " + e);
                }

                /* Now that we've read all the lines, allocate some arrays.
                 */
                blocklen = new int[ (oldinfo.maxLine>newinfo.maxLine?
                        oldinfo.maxLine : newinfo.maxLine) + 2 ];
                oldinfo.alloc();
                newinfo.alloc();

                /* Now do the work, and print the results. */
                transform();
                printout();
                //stat.printSummary("appverificationID");
        }

        /**
         * inputscan    Reads the file specified by pinfo.file.
         * ---------    Places the lines of that file in the symbol table.
         *              Sets pinfo.maxLine to the number of lines found.
         */
        void inputscan( fileInfo pinfo ) throws IOException
        {
             String linebuffer;

             pinfo.maxLine = 0;
             while ((linebuffer = pinfo.file.readLine()) != null) {
                       storeline( linebuffer, pinfo );
             }
        }

        /**
         * storeline    Places line into symbol table.
         * ---------    Expects pinfo.maxLine initted: increments.
         *              Places symbol table handle in pinfo.ymbol.
         *              Expects pinfo is either oldinfo or newinfo.
         */
        void storeline( String linebuffer, fileInfo pinfo )
        {
             int linenum = ++pinfo.maxLine;    /* note, no line zero */
             if ( linenum > fileInfo.MAXLINECOUNT ) {
                  System.err.println( "MAXLINECOUNT exceeded, must stop." );
                  System.exit(1);
             }
             pinfo.symbol[ linenum ] =
                  node.addSymbol( linebuffer, pinfo == oldinfo, linenum );
        }

        /*
         * transform
         * Analyzes the file differences and leaves its findings in
         * the global arrays oldinfo.other, newinfo.other, and blocklen.
         * Expects both files in symtab.
         * Expects valid "maxLine" and "symbol" in oldinfo and newinfo.
         */
        void transform()
        {
             int oldline, newline;
             int oldmax = oldinfo.maxLine + 2;  /* Count pseudolines at  */
             int newmax = newinfo.maxLine + 2;  /* ..front and rear of file */

             for (oldline=0; oldline < oldmax; oldline++ )
                        oldinfo.other[oldline]= -1;
             for (newline=0; newline < newmax; newline++ )
                        newinfo.other[newline]= -1;

             scanunique();  /* scan for lines used once in both files */
             scanafter();   /* scan past sure-matches for non-unique blocks */
             scanbefore();  /* scan backwards from sure-matches */
             scanblocks();  /* find the fronts and lengths of blocks */
        }

        /*
         * scanunique
         * Scans for lines which are used exactly once in each file.
         * Expects both files in symtab, and oldinfo and newinfo valid.
         * The appropriate "other" array entries are set to the line# in
         * the other file.
         * Claims pseudo-lines at 0 and XXXinfo.maxLine+1 are unique.
         */
        void scanunique()
        {
             int oldline, newline;
             node psymbol;

             for( newline = 1; newline <= newinfo.maxLine; newline++ ) {
                  psymbol = newinfo.symbol[ newline ];
                  if ( psymbol.symbolIsUnique()) {        // 1 use in each file
                       oldline = psymbol.linenum;
                       newinfo.other[ newline ] = oldline; // record 1-1 map
                       oldinfo.other[ oldline ] = newline;
                  }
             }
             newinfo.other[ 0 ] = 0;
             oldinfo.other[ 0 ] = 0;
             newinfo.other[ newinfo.maxLine + 1 ] = oldinfo.maxLine + 1;
             oldinfo.other[ oldinfo.maxLine + 1 ] = newinfo.maxLine + 1;
        }

        /*
         * scanafter
         * Expects both files in symtab, and oldinfo and newinfo valid.
         * Expects the "other" arrays contain positive #s to indicate
         * lines that are unique in both files.
         * For each such pair of places, scans past in each file.
         * Contiguous groups of lines that match non-uniquely are
         * taken to be good-enough matches, and so marked in "other".
         * Assumes each other[0] is 0.
         */
        void scanafter()
        {
             int oldline, newline;

             for( newline = 0; newline <= newinfo.maxLine; newline++ ) {
                  oldline = newinfo.other[ newline ];
                  if ( oldline >= 0 ) {        /* is unique in old & new */
                       for(;;) {        /* scan after there in both files */
                            if ( ++oldline > oldinfo.maxLine   ) break;
                            if ( oldinfo.other[ oldline ] >= 0 ) break;
                            if ( ++newline > newinfo.maxLine   ) break;
                            if ( newinfo.other[ newline ] >= 0 ) break;

                            /* oldline & newline exist, and
                                aren't already matched */

                            if ( newinfo.symbol[ newline ] !=
                                oldinfo.symbol[ oldline ] ) break;  // not same

                            newinfo.other[newline] = oldline; // record a match
                            oldinfo.other[oldline] = newline;
                       }
                  }
             }
        }

        /**
         * scanbefore
         * As scanafter, except scans towards file fronts.
         * Assumes the off-end lines have been marked as a match.
         */
        void scanbefore()
        {
             int oldline, newline;

             for( newline = newinfo.maxLine + 1; newline > 0; newline-- ) {
                  oldline = newinfo.other[ newline ];
                  if ( oldline >= 0 ) {               /* unique in each */
                       for(;;) {
                            if ( --oldline <= 0                ) break;
                            if ( oldinfo.other[ oldline ] >= 0 ) break;
                            if ( --newline <= 0                ) break;
                            if ( newinfo.other[ newline ] >= 0 ) break;

                            /* oldline and newline exist,
                                and aren't marked yet */

                            if ( newinfo.symbol[ newline ] !=
                                oldinfo.symbol[ oldline ] ) break;  // not same

                            newinfo.other[newline] = oldline; // record a match
                            oldinfo.other[oldline] = newline;
                       }
                  }
             }
        }

        /**
         * scanblocks - Finds the beginnings and lengths of blocks of matches.
         * Sets the blocklen array (see definition).
         * Expects oldinfo valid.
         */
        void scanblocks()
        {
             int oldline, newline;
             int oldfront = 0;      // line# of front of a block in old, or 0
             int newlast = -1;      // newline's value during prev. iteration

             for( oldline = 1; oldline <= oldinfo.maxLine; oldline++ )
                       blocklen[ oldline ] = 0;
             blocklen[ oldinfo.maxLine + 1 ] = UNREAL; // starts a mythical blk

             for( oldline = 1; oldline <= oldinfo.maxLine; oldline++ ) {
                  newline = oldinfo.other[ oldline ];
                  if ( newline < 0 ) oldfront = 0;  /* no match: not in block */
                  else{                                   /* match. */
                       if ( oldfront == 0 )         oldfront = oldline;
                       if ( newline != (newlast+1)) oldfront = oldline;
                       ++blocklen[ oldfront ];
                  }
                  newlast = newline;
             }
        }

        /* The following are global to printout's subsidiary routines */
        // enum{ idle, delete, insert, movenew, moveold,
        // same, change } printstatus;
        public static final int
                idle = 0, delete = 1, insert = 2, movenew = 3, moveold = 4,
                same = 5, change = 6;
        int printstatus;
        boolean anyprinted;
        int printoldline, printnewline;     // line numbers in old & new file

        /**
         * printout - Prints summary to stdout.
         * Expects all data structures have been filled out.
         */
        void printout()
        {
             printstatus = idle;
             anyprinted = false;
             for( printoldline = printnewline = 1; ; ) {
                  if ( printoldline > oldinfo.maxLine ) { newconsume(); break;}
                  if ( printnewline > newinfo.maxLine ) { oldconsume(); break;}
                  if (      newinfo.other[ printnewline ] < 0 ) {
                       if ( oldinfo.other[ printoldline ] < 0 )
                                showchange();
                       else
                                showinsert();
                  }
                  else if ( oldinfo.other[ printoldline ] < 0 )
                        showdelete();
                  else if ( blocklen[ printoldline ] < 0 )
                        skipold();
                  else if ( oldinfo.other[ printoldline ] == printnewline )
                        showsame();
                  else
                        showmove();
             }

             if ( anyprinted == true )
                 {
                println( ">>>> End of differences."  );
                 //stat.addStatus("appverification bookstore", stat.FAIL);
                 }

             else
                 {
                 println( ">>>> Files are identical." );
                 //stat.addStatus("appverification bookstore", stat.PASS);
                 }


        }

        /*
         * newconsume        Part of printout. Have run out of old file.
         * Print the rest of the new file, as inserts and/or moves.
         */
        void newconsume()
        {
             for(;;) {
                  if ( printnewline > newinfo.maxLine )
                        break;        /* end of file */
                  if ( newinfo.other[ printnewline ] < 0 ) showinsert();
                  else                                    showmove();
             }
        }

        /**
         * oldconsume        Part of printout. Have run out of new file.
         * Process the rest of the old file, printing any
         * parts which were deletes or moves.
         */
        void oldconsume()
        {
             for(;;) {
                  if ( printoldline > oldinfo.maxLine )
                        break;       /* end of file */
                  printnewline = oldinfo.other[ printoldline ];
                  if ( printnewline < 0 ) showdelete();
                  else if ( blocklen[ printoldline ] < 0 ) skipold();
                  else showmove();
             }
        }

        /**
         * showdelete        Part of printout.
         * Expects printoldline is at a deletion.
         */
        void showdelete()
        {
                if ( printstatus != delete )
                {
                    println("Following test didn't get run-------->");
                    //println( ">>>>>>>>>>>>>>>>> DELETE AT " + printoldline);
                }
                printstatus = delete;
                oldinfo.symbol[ printoldline ].showSymbol();
                anyprinted = true;
                printoldline++;
        }

        /*
         * showinsert        Part of printout.
         * Expects printnewline is at an insertion.
         */
        void showinsert()
        {
             if ( printstatus == change ) println( ">>>>>>>>>>>>>     CHANGED TO" );
             else if ( printstatus != insert )
                  println( ">>>>>>>>>>>>>>>> INSERT BEFORE " + printoldline );
             printstatus = insert;
             newinfo.symbol[ printnewline ].showSymbol();
             anyprinted = true;
             printnewline++;
        }

        /**
         * showchange        Part of printout.
         * Expects printnewline is an insertion.
         *  Expects printoldline is a deletion.
         */
        void showchange()
        {
             if ( printstatus != change )
                  println( ">>>>>>>>>>>>>>>>>>>>> " + printoldline + " CHANGED FROM");
             printstatus = change;
             oldinfo.symbol[ printoldline ].showSymbol();
             anyprinted = true;
             printoldline++;
        }

        /**
         * skipold           Part of printout.
         * Expects printoldline at start of an old block that has
         * already been announced as a move.
         * Skips over the old block.
         */
        void skipold()
        {
             printstatus = idle;
             for(;;) {
                  if ( ++printoldline > oldinfo.maxLine )
                        break;     /* end of file  */
                  if ( oldinfo.other[ printoldline ] < 0 )
                        break;    /* end of block */
                  if ( blocklen[ printoldline ]!=0)
                        break;          /* start of another */
             }
        }

        /**
         * skipnew           Part of printout.
         * Expects printnewline is at start of a new block that has
         * already been announced as a move.
         * Skips over the new block.
         */
        void skipnew()
        {
             int oldline;
             printstatus = idle;
             for(;;) {
                  if ( ++printnewline > newinfo.maxLine )
                        break;    /* end of file  */
                  oldline = newinfo.other[ printnewline ];
                  if ( oldline < 0 )
                        break;                         /* end of block */
                  if ( blocklen[ oldline ] != 0)
                        break;              /* start of another */
             }
        }

        /**
         * showsame          Part of printout.
         * Expects printnewline and printoldline at start of
         * two blocks that aren't to be displayed.
         */
        void showsame()
        {
             int count;
             printstatus = idle;
             if ( newinfo.other[ printnewline ] != printoldline ) {
                  System.err.println("BUG IN LINE REFERENCING");
                  System.exit(1);
             }
             count = blocklen[ printoldline ];
             printoldline += count;
             printnewline += count;
        }

        /**
         * showmove          Part of printout.
         * Expects printoldline, printnewline at start of
         * two different blocks ( a move was done).
         */
        void showmove()
        {
             int oldblock = blocklen[ printoldline ];
             int newother = newinfo.other[ printnewline ];
             int newblock = blocklen[ newother ];

             if ( newblock < 0 ) skipnew();         // already printed.
             else if ( oldblock >= newblock ) {     // assume new's blk moved.
                  blocklen[newother] = -1;         // stamp block as "printed".
                  println( ">>>> " + newother +
                        " THRU " + (newother + newblock - 1) +
                        " MOVED TO BEFORE " + printoldline );
                  for( ; newblock > 0; newblock--, printnewline++ )
                       newinfo.symbol[ printnewline ].showSymbol();
                  anyprinted = true;
                  printstatus = idle;

             } else                /* assume old's block moved */
                  skipold();      /* target line# not known, display later */
        }

        /** Convenience wrapper for println */
        public void println(String s) {
                System.out.println(s);
        }
};                                // end of main class!

/**
 * Class "node". The symbol table routines in this class all
 * understand the symbol table format, which is a binary tree.
 * The methods are: addSymbol, symbolIsUnique, showSymbol.
 */
class node{                       /* the tree is made up of these nodes */
        node pleft, pright;
        int linenum;

        static final int freshnode = 0,
        oldonce = 1, newonce = 2, bothonce = 3, other = 4;

        int /* enum linestates */ linestate;
        String line;

        static node panchor = null;    /* symtab is a tree hung from this */

        /**
         * Construct a new symbol table node and fill in its fields.
         * @param        string        A line of the text file
         */
        node( String pline)
        {
             pleft = pright = null;
             linestate = freshnode;
             /* linenum field is not always valid */
             line = pline;
        }

        /**
         * matchsymbol       Searches tree for a match to the line.
         * @param        String        pline, a line of text
         * If node's linestate == freshnode, then created the node.
         */
        static node matchsymbol( String pline )
        {
             int comparison;
             node pnode = panchor;
             if ( panchor == null ) return panchor = new node( pline);
             for(;;) {
                  comparison = pnode.line.compareTo(pline);
                  if ( comparison == 0 ) return pnode;          /* found */

                  if ( comparison < 0 ) {
                       if ( pnode.pleft == null ) {
                            pnode.pleft = new node( pline);
                            return pnode.pleft;
                       }
                       pnode = pnode.pleft;
                  }
                  if ( comparison > 0 ) {
                       if ( pnode.pright == null ) {
                            pnode.pright = new node( pline);
                            return pnode.pright;
                       }
                       pnode = pnode.pright;
                  }
             }
             /* NOTE: There are return stmts, so control does not get here. */
        }

        /**
         * addSymbol(String pline) - Saves line into the symbol table.
         * Returns a handle to the symtab entry for that unique line.
         * If inoldfile nonzero, then linenum is remembered.
         */
        static node addSymbol( String pline, boolean inoldfile, int linenum )
        {
                node pnode;
                pnode = matchsymbol( pline );  /* find the node in the tree */
                if ( pnode.linestate == freshnode ) {
                        pnode.linestate = inoldfile ? oldonce : newonce;
                } else {
                  if (( pnode.linestate == oldonce && !inoldfile ) ||
                      ( pnode.linestate == newonce &&  inoldfile ))
                       pnode.linestate = bothonce;
                  else pnode.linestate = other;
                }
                if (inoldfile) pnode.linenum = linenum;
                return pnode;
        }

        /**
         * symbolIsUnique    Arg is a ptr previously returned by addSymbol.
         * --------------    Returns true if the line was added to the
         *                   symbol table exactly once with inoldfile true,
         *                   and exactly once with inoldfile false.
         */
        boolean symbolIsUnique()
        {
                return (linestate == bothonce );
        }

        /**
         * showSymbol        Prints the line to stdout.
         */
        void showSymbol()
        {
                System.out.println(line);
        }
}
