/* FichothequeLib_Tools - Copyright (c) 2008-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.fichotheque.tools.exportation.table;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import net.fichotheque.SubsetKey;
import net.fichotheque.exportation.table.JunctionTableExportInfo;


/**
 *
 * @author Vincent Calame
 */
public class JunctionParser {

    private Result result = new Result();
    private String currentTableNameLine = null;
    private String currentSubsetKey1Line = null;
    private String currentSubsetKey2Line = null;
    private int currentLineNumber;
    private int firstLineNumber;

    public JunctionParser() {
    }

    public static Result parse(Reader reader) throws IOException {
        JunctionParser parser = new JunctionParser();
        LineNumberReader lineNumberReader = new LineNumberReader(reader);
        String line = null;
        while ((line = lineNumberReader.readLine()) != null) {
            int lineNumber = lineNumberReader.getLineNumber();
            line = line.trim();
            if (line.length() == 0) {
                parser.flush();
            } else if (line.startsWith("#")) {
                continue;
            } else {
                parser.addLine(line, lineNumber);
            }
        }
        parser.flush();
        return parser.result;
    }

    private void flush() {
        if (currentTableNameLine != null) {
            if (currentSubsetKey1Line == null) {
                //errorHandler.missingFormatSourceLineError(firstLineNumber + 2);
                clear();
                return;
            }
            if (currentSubsetKey2Line == null) {
                //errorHandler.missingFormatSourceLineError(firstLineNumber + 2);
                clear();
                return;
            }
            SubsetKey subsetKey1 = null;
            SubsetKey subsetKey2 = null;
            try {
                subsetKey1 = SubsetKey.parse(currentSubsetKey1Line);
            } catch (ParseException pe) {
                clear();
                return;
            }
            try {
                subsetKey2 = SubsetKey.parse(currentSubsetKey2Line);
            } catch (ParseException pe) {
                clear();
                return;
            }
            result.add(currentTableNameLine, subsetKey1, subsetKey2);
            clear();
        }

    }

    private void addLine(String line, int currentLineNumber) {
        this.currentLineNumber = currentLineNumber;
        if (currentTableNameLine == null) {
            currentTableNameLine = line;
            firstLineNumber = currentLineNumber;
        } else if (currentSubsetKey1Line == null) {
            currentSubsetKey1Line = line;
        } else if (currentSubsetKey2Line == null) {
            currentSubsetKey2Line = line;
        } else {
            //errorHandler.tooManyLineWarning(currentLineNumber, line);
        }
    }

    private void clear() {
        currentTableNameLine = null;
        currentSubsetKey1Line = null;
        currentSubsetKey2Line = null;
    }


    public static class Result {

        List<JunctionTableExportInfo> junctionTableExportInfoList = new ArrayList<JunctionTableExportInfo>();

        void add(String name, SubsetKey subsetKey1, SubsetKey subsetKey2) {
            junctionTableExportInfoList.add(new InternalJunctionTableExportInfo(name, subsetKey1, subsetKey2));
        }

        public List<JunctionTableExportInfo> getJunctionTableExportInfoList() {
            return junctionTableExportInfoList;
        }

    }


    private static class InternalJunctionTableExportInfo implements JunctionTableExportInfo {

        String tableName;
        SubsetKey subsetKey1;
        SubsetKey subsetKey2;

        InternalJunctionTableExportInfo(String name, SubsetKey subsetKey1, SubsetKey subsetKey2) {
            this.tableName = name;
            this.subsetKey1 = subsetKey1;
            this.subsetKey2 = subsetKey2;
        }

        public String getTableName() {
            return tableName;
        }

        public SubsetKey getSubsetKey1() {
            return subsetKey1;
        }

        public SubsetKey getSubsetKey2() {
            return subsetKey2;
        }

    }

}
