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