package de.duehl.vocabulary.japanese.website.update.ownlists.groupfile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.duehl.basics.io.Charset;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.text.Text;
import de.duehl.vocabulary.japanese.website.update.ownlists.groupfile.data.GroupFileEntry;

/**
 * Diese Klasse parst den Inhalt einer Gruppendatei, wie sie den ZIP-Archiven der Gruppen beigelegt
 * werden.
 *
 * In dieser Datei halte ich fest, zu welcher Listendatei welcher langer Name (mit Leerzeichen
 * etc.) gehört, damit man die Listen im Vokabeltrainer dann unter ihren originalen Namen
 * importieren kann.
 *
 * Der Inhalt enthält Zeilen der folgenden Art, wobei als Trenner ein Tabulator benutzt wird:
 *     b1K011SchreibbarMitAIUEO.owl -> B1 K01 1 Schreibbar mit a i u e o
 *
 * @version 1.01     2024-10-14
 * @author Christian Dühl
 */

public class GroupFileIo {

    /**
     * Der Dateiname (ohne Pfad) der Gruppendatei, welche in jede Zip-Datei einer Gruppe mit
     * beigelegt wird und die Zuordnung der Dateinamen Listen ohne Pfad zur Langform des
     * Listennamens (mit Leerzeichen ...) enthält.
     *
     * Der Inhalt enthält Zeilen der folgenden Art, wobei als Trenner ein Tabulator benutzt wird:
     *     b1K011SchreibbarMitAIUEO.owl -> B1 K01 1 Schreibbar mit a i u e o
     */
    public static final String GROUP_BARE_FILENAME = "group.grp";

    /** Der Zeichensatz in dem die Gruppendatei abgespeichert wird. */
    private static final Charset GROUP_FILE_CHARSET = Charset.UTF_8;

    /**
     * Hier wird die der Inhalt der Gruppendatei erstellt.
     *
     * @param groupName
     *            Der Name der Gruppe ("FROM_ZERO_1").
     * @param listNamesByGroupNameMap
     *            Das Verzeichnis der Listennamen (mit Leerzeichen etc.) der zu den Gruppen
     *            gehörigen Listen nach dem Gruppennamen.
     *
     *            Die Listennamen sind die selben, wie sie auch in der Datei
     *                c:\Users\XYZXYZ\.JapaneseVocableTrainer\own_vocable_lists\vokabellisten.nam
     *            stehen.
     * @param listFilenameByListNameMap
     *            Das Verzeichnis der echten Listendateien zum Listennamen.
     * @return Text mit dem Inhalt der Gruppendatei.
     */
    public static String createGroupFileContent(String groupName,
            Map<String, List<String>> listNamesByGroupNameMap,
            Map<String, String> listFilenameByListNameMap) {
        List<String> lines = new ArrayList<>();

        for (String listName : listNamesByGroupNameMap.get(groupName)) {
            String listFilenameC = listFilenameByListNameMap.get(listName);
            String bareListFilename = FileHelper.getBareName(listFilenameC);
            String line = bareListFilename + "\t" + listName;
            lines.add(line);
        }

        return Text.joinWithLineBreak(lines);
    }

    /**
     * Schreibt die Gruppendatei raus.
     *
     * @param filename
     *            Der Dateiname.
     * @param content
     *            Der Inhalt der Datei.
     */
    public static void writeGroupFile(String filename, String content) {
        FileHelper.writeTextToFile(content, filename, GROUP_FILE_CHARSET);
    }

    /**
     * List eine Gruppendatei in eine Liste mit den Objekten zu jeder Zeile ein.
     *
     * @param filename
     *            Der Name der Gruppendatei.
     */
    public static List<GroupFileEntry> readGroupFile(String filename) {
        List<GroupFileEntry> entries = new ArrayList<>();

        List<String> lines = FileHelper.readFileToList(filename, GROUP_FILE_CHARSET);
        for (String line : lines) {
            if (line.isBlank()) {
                continue;
            }

            List<String> parts = Text.splitByTabulator(line);
            if (parts.size() != 2) {
                return new ArrayList<>();
            }
            String listBareFilename = parts.get(0);
            String listName = parts.get(1);
            entries.add(new GroupFileEntry(listBareFilename, listName));
        }

        return entries;
    }

    /**
     * Erstellt aus dem eingelesenen Inhalt der Gruppendatei ein Verzeichnis der Listennamen (mit
     * Leerzeichen etc.) nach den Dateinamen der Listen (ohne Pfad).
     *
     * @param entries
     *            Die Liste mit den Objekten zu jeder Zeile der Datei.
     * @return Das Verzeichnis der Listennamen (mit Leerzeichen etc.) nach den Dateinamen der
     *         Listen (ohne Pfad).
     */
    public static Map<String, String> createListNameByBareListFilenameMap(
            List<GroupFileEntry> entries) {
        Map<String, String> listNameByBareListFilenameMap = new HashMap<>();

        for (GroupFileEntry entry : entries) {
            String listBareFilename = entry.getListBareFilename();
            String listName = entry.getListName();
            listNameByBareListFilenameMap.put(listBareFilename, listName);
        }

        return listNameByBareListFilenameMap;
    }

    /**
     * Erstellt aus dem eingelesenen Inhalt der Gruppendatei ein Verzeichnis der Dateinamen der
     * Listen (ohne Pfad) nach den Listennamen (mit Leerzeichen etc.).
     *
     * @param entries
     *            Die Liste mit den Objekten zu jeder Zeile der Datei.
     * @return Das Verzeichnis der Dateinamen der Listen (ohne Pfad) nach den Listennamen (mit
     *         Leerzeichen etc.).
     */
    public static Map<String, String> createBareListFilenameByListNameMap(
            List<GroupFileEntry> entries) {
        Map<String, String> bareListFilenameByListNameMap = new HashMap<>();

        for (GroupFileEntry entry : entries) {
            String listBareFilename = entry.getListBareFilename();
            String listName = entry.getListName();
            bareListFilenameByListNameMap.put(listName, listBareFilename);
        }

        return bareListFilenameByListNameMap;
    }

}
