package de.duehl.basics.io.textfile.split;

/*
 * Copyright 2019 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 java.util.List;

import de.duehl.basics.io.Charset;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.io.FineFileWriter;
import de.duehl.basics.io.Writer;

/**
 * Diese Klasse liest in Teile aufgeteilte Textdateien wieder ein und erzeugt eine Gesamtdatei.
 *
 * @version 1.01     2019-12-03
 * @author Christian Dühl
 */

public class SplittedTextFileJoiner {

    /** Namen der erzeugten aufgeteilten Dateien. */
    private List<String> filenamesOfSplitFiles;

    /** Name der zu erzeugenden Gesamtdatei. */
    private final String joinedFilename;

    /** Kodierung der aufzuteilenden Textdatei wie auch der Gesamtdatei. */
    private final Charset charset;

    /** Gibt an, ob die aufgeteilten Dateien in der ersten Zeile Titel enthalten. */
    private final boolean hasTitles;

    /** Erlaubt (true, default) oder verhindert (false) Ausgaben auf STDOUT. */
    private boolean verbose;

    /**
     * Konstruktor.
     *
     * @param filenamesOfSplitFiles
     *            Namen der erzeugten aufgeteilten Dateien.
     * @param joinedFilename
     *            Name der zu erzeugenden Gesamtdatei.
     * @param charset
     *            Kodierung der aufzuteilenden Textdatei wie auch der Gesamtdatei.
     * @param hasTitles
     *            Gibt an, ob die aufgeteilten Dateien in der ersten Zeile Titel enthalten.
     */
    public SplittedTextFileJoiner(List<String> filenamesOfSplitFiles,
            String joinedFilename, Charset charset, boolean hasTitles) {
        this.filenamesOfSplitFiles = filenamesOfSplitFiles;
        this.joinedFilename = joinedFilename;
        this.charset = charset;
        this.hasTitles = hasTitles;

        verbose = true;
    }

    /** Verhindert Ausgaben auf STDOUT. */
    public void beQuiet() {
        verbose = false;
    }

    /** Setzt die Teile der Datei zusammen. */
    public void work() {
        boolean titleLineWritten = false;
        Writer writer = new FineFileWriter(joinedFilename, charset);

        for (String filenameOfSplitFile : filenamesOfSplitFiles) {
            List<String> lines = FileHelper.readFileToList(filenameOfSplitFile, charset);
            /*
             * Hier gehe ich davon aus, dass eine aufgeteilte Datei in den Speicher passt... Könnte
             * man natürlich anpassen und von Hand lesen und so immer nur eine Zeile vorrätig
             * halten.
             */
            if (lines.isEmpty()) {
                throw new RuntimeException(
                        "Die aufgeteilte Datei " + filenameOfSplitFile + " ist leer.");
            }
            if (!titleLineWritten && hasTitles) {
                writer.writeln(lines.get(0));
                titleLineWritten = true;
            }
            int startIndex = hasTitles ? 1 : 0;
            for (int index = startIndex; index < lines.size(); ++index) {
                String line = lines.get(index);
                writer.writeln(line);
            }
            say("Datei " + filenameOfSplitFile + " gelesen.");
        }

        writer.close();
        say("Ergebnisdatei " + joinedFilename + " erzeugt.");
    }

    private void say(String message) {
        if (verbose) {
            System.out.println(message);
        }
    }

}
