package de.duehl.basics.io.textfile;

/*
 * Copyright 2021 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import de.duehl.basics.io.Charset;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.io.FineFileReader;
import de.duehl.basics.io.Reader;

import de.duehl.basics.text.Text;

/**
 * Diese Klasse bietet Methoden rund um die Behandlung von Texten.
 *
 * @version 1.01     2021-03-08
 * @author Christian Dühl
 */

public class TextFileCompare {

    /** Zeichensatz der einzulesenden Datei (z.B. ISO_8859_1, UTF_8). */
    private final Charset charset;

    /** Falls isContentEqual() false liefert, ist hier der Grund für den Unterschied enthalten. */
    private String differenceMessage;

    /** Konstruktor. */
    public TextFileCompare() {
        this(Charset.ISO_8859_1);
    }

    /**
     * Konstruktor.
     *
     * @param charset
     *            Zeichensatz der einzulesenden Datei (z.B. ISO_8859_1).
     */
    public TextFileCompare(Charset charset) {
        this.charset = charset;

        differenceMessage = "";
    }

    /**
     * Prüft die beiden übergebenen Dateien auf inhaltliche Gleichheit.
     *
     * @param firstFilename
     *            Name der ersten zu vergleichenden Datei.
     * @param secondFilename
     *            Name der zweiten zu vergleichenden Datei.
     * @return Wahrheitswert, true genau dann, wenn beide Dateien existieren und inhaltlich
     *         identisch sind.
     */
    public boolean isContentEqual(String firstFilename, String secondFilename) {
        if (!FileHelper.exists(firstFilename)) {
            differenceMessage = "Die erste Datei ist nicht vorhanden.\n"
                    + "\t" + "erste Datei : " + firstFilename + "\n"
                    + "\t" + "zweite Datei: " + secondFilename + "\n";
            return false;
        }
        if (!FileHelper.exists(secondFilename)) {
            differenceMessage = "Die zweite Datei ist nicht vorhanden.\n"
                    + "\t" + "erste Datei : " + firstFilename + "\n"
                    + "\t" + "zweite Datei: " + secondFilename + "\n";
            return false;
        }

        Reader firstReader = new FineFileReader(firstFilename, charset);
        Reader secondReader = new FineFileReader(secondFilename, charset);

        boolean loop = true;
        boolean equals = true;


        while (loop) {
            String firstLine = firstReader.readNextLine();
            String secondLine = secondReader.readNextLine();

            /* Beide Dateien sind komplett eingelesen: */
            if (null == firstLine && null == secondLine) {
                loop = false;
            }
            /* Nur die erste Datei ist komplett eingelesen: */
            else if (null == firstLine) {
                loop = false;
                equals = false;
                differenceMessage = "Die zweite Datei ist länger als die erste.\n"
                        + "\t" + "erste Datei : " + firstFilename + "\n"
                        + "\t" + "zweite Datei: " + secondFilename + "\n";
            }
            /* Nur die zweite Datei ist komplett eingelesen: */
            else if (null == secondLine) {
                loop = false;
                equals = false;
                differenceMessage = "Die erste Datei ist länger als die zweite.\n"
                        + "\t" + "erste Datei : " + firstFilename + "\n"
                        + "\t" + "zweite Datei: " + secondFilename + "\n";
            }
            /* Anderenfalls inhaltlicher Vergleich der beiden Zeilen: */
            else if  (!firstLine.equals(secondLine)) {
                loop = false;
                equals = false;
                differenceMessage = "Die beiden Dateien unterscheiden sich in Zeile "
                        + firstReader.getLineNumber() + ".\n"
                        + "\t" + "erste Datei            : " + firstFilename + "\n"
                        + "\t" + "zweite Datei           : " + secondFilename + "\n"
                        + "\t" + "Unterschied            : \n"
                                + Text.indent(
                                        Text.lineDifference(firstLine, secondLine), 4) + "\n"
                        + "\t" + "Zeile aus erster Datei : " + firstLine + "\n"
                        + "\t" + "Zeile aus zweiter Datei: " + secondLine + "\n";
            }
        }

        secondReader.close();
        firstReader.close();

        return equals;
    }

    /**
     * Falls isContentEqual() false liefert (oder eine Ausnahme wirft), kann mit dieser Methode der
     * Grund für den Unterschied abgefragt werden.
     */
    public String getDifferenceMessage() {
        return differenceMessage;
    }

}
