/* FichothequeLib_Tools - Copyright (c) 2013-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.importation.parsers;

import java.text.ParseException;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.metadata.ThesaurusFieldKey;
import net.fichotheque.tools.importation.ParseResultBuilder;
import net.fichotheque.tools.importation.thesaurus.MergeThesaurusImportBuilder;


/**
 *
 * @author Vincent Calame
 */
class ThesaurusMergeRowParser extends ThesaurusRowParser {

    private final int originIndex;
    private final boolean isOriginIdalpha;
    private final int destinationIndex;
    private final boolean isDestinationIdalpha;
    private final MergeThesaurusImportBuilder mergeThesaurusImportBuilder;
    private final ParseResultBuilder parseResultBuilder;

    private ThesaurusMergeRowParser(MergeThesaurusImportBuilder mergeThesaurusImportBuilder, ParseResultBuilder parseResultBuilder, int originIndex, boolean isOriginIdalpha, int destinationIndex, boolean isDestinationIdalpha) {
        this.mergeThesaurusImportBuilder = mergeThesaurusImportBuilder;
        this.parseResultBuilder = parseResultBuilder;
        this.originIndex = originIndex;
        this.isOriginIdalpha = isOriginIdalpha;
        this.destinationIndex = destinationIndex;
        this.isDestinationIdalpha = isDestinationIdalpha;
    }

    @Override
    public MergeThesaurusImportBuilder getThesaurusImportBuilder() {
        return mergeThesaurusImportBuilder;
    }

    @Override
    public void parseRow(int rowNumber, Row row) {
        Motcle motcle = getMotcle(mergeThesaurusImportBuilder.getThesaurus(), originIndex, isOriginIdalpha, rowNumber, row);
        Motcle destinationMotcle = getMotcle(mergeThesaurusImportBuilder.getDestinationThesaurus(), destinationIndex, isDestinationIdalpha, rowNumber, row);
        if ((motcle != null) && (destinationMotcle != null)) {
            mergeThesaurusImportBuilder.add(motcle, destinationMotcle);
        }
    }

    private Motcle getMotcle(Thesaurus thesaurus, int index, boolean isIdalpha, int lineNumber, Row row) {
        if (row.getColumnCount() <= index) {
            parseResultBuilder.missingIdColumn(lineNumber);
            return null;

        }
        String idString = row.getColumnValue(index).trim();
        Motcle motcle = null;
        if (isIdalpha) {
            motcle = thesaurus.getMotcleByIdalpha(idString);
            if (motcle == null) {
                parseResultBuilder.unknownIdalpha(lineNumber, idString);
            }
        } else {
            try {
                int id = Integer.parseInt(idString);
                motcle = thesaurus.getMotcleById(id);
                if (motcle == null) {
                    parseResultBuilder.unknownId(lineNumber, idString);
                }
            } catch (NumberFormatException nfe) {
                parseResultBuilder.notIntegerId(lineNumber, idString);
            }
        }
        return motcle;
    }

    static ThesaurusMergeRowParser newInstance(String[] fieldArray, MergeThesaurusImportBuilder mergeThesaurusImportBuilder, ParseResultBuilder parseResultBuilder) {
        int originIndex = -1;
        int idalphaOriginIndex = -1;
        int destinationIndex = -1;
        int destinationIdalphaIndex = -1;
        int length = fieldArray.length;
        for (int i = 0; i < length; i++) {
            String field = fieldArray[i].trim();
            if ((field.equals("destination_id")) || (field.equals("destination_idths"))) {
                if (destinationIndex != -1) {
                    destinationIndex = i;
                }
            } else if (field.equals("destination_idalpha")) {
                if (destinationIdalphaIndex != -1) {
                    destinationIdalphaIndex = i;
                }
            } else {
                ThesaurusFieldKey thesaurusFieldKey;
                try {
                    thesaurusFieldKey = ThesaurusFieldKey.parse(field);
                } catch (ParseException pe) {
                    continue;
                }
                if (thesaurusFieldKey.equals(ThesaurusFieldKey.ID)) {
                    if (originIndex == -1) {
                        originIndex = i;
                    }
                } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.IDALPHA)) {
                    if (idalphaOriginIndex == -1) {
                        idalphaOriginIndex = i;
                    }
                }
            }
        }
        boolean isOriginIdalpha = false;
        boolean isDestinationIdalpha = false;
        if (originIndex == -1) {
            if (mergeThesaurusImportBuilder.getThesaurus().isIdalphaType()) {
                if (idalphaOriginIndex != -1) {
                    originIndex = idalphaOriginIndex;
                    isOriginIdalpha = true;
                } else {
                    parseResultBuilder.missingColumns(ThesaurusFieldKey.ID.toString(), ThesaurusFieldKey.IDALPHA.toString());
                }
            } else {
                parseResultBuilder.missingColumn(ThesaurusFieldKey.ID.toString());
            }
        }
        if (destinationIndex == -1) {
            if (mergeThesaurusImportBuilder.getDestinationThesaurus().isIdalphaType()) {
                if (idalphaOriginIndex != -1) {
                    destinationIndex = destinationIdalphaIndex;
                    isDestinationIdalpha = true;
                } else {
                    parseResultBuilder.missingColumns("destination_id", "destination_idalpha");
                }
            } else {
                parseResultBuilder.missingColumn("destination_id");
            }
        }
        if ((originIndex != -1) && (destinationIndex != - 1)) {
            return new ThesaurusMergeRowParser(mergeThesaurusImportBuilder, parseResultBuilder, originIndex, isOriginIdalpha, destinationIndex, isDestinationIdalpha);
        } else {
            return null;
        }
    }

}
