/*
 * Copyright (c) 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);
	}
}
