/* 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;

import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
import net.fichotheque.FichothequeQuestioner;
import net.fichotheque.Subset;
import net.fichotheque.SubsetItem;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.HtmlConverter;
import net.fichotheque.importation.CorpusImport;
import net.fichotheque.importation.ImportationContext;
import net.fichotheque.importation.ThesaurusImport;
import net.fichotheque.importation.TiesImport;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.html.HtmlCleaner;
import net.mapeadores.util.text.Label;


/**
 *
 * @author Vincent Calame
 */
public final class ImportationUtils {

    public final static TiesImport EMPTY_TIESIMPORT = new EmptyTiesImport();
    public final static List<TiesImport.TieImport> EMPTY_TIESIMPORTLIST = Collections.emptyList();

    private ImportationUtils() {

    }

    public static CorpusImport.FicheImport toFicheImport(FicheMeta ficheMeta) {
        return new InternalFicheImport(ficheMeta.getId());
    }

    public static ThesaurusImport.MotcleImport toMotcleImport(Motcle motcle) {
        return new InternalMotcleImport(motcle.getId());
    }

    public static TiesImport.TieImport toTieImport(IncludeKey includeKey, Subset subset, int otherId, int weight) {
        return new InternalTieImport(includeKey, subset, new InternalIdOther(otherId), weight);
    }

    public static TiesImport.TieImport toTieImport(IncludeKey includeKey, SubsetItem otherSubsetItem, int weight) {
        return new InternalTieImport(includeKey, otherSubsetItem.getSubset(), new InternalIdOther(otherSubsetItem.getId()), weight);
    }

    public static TiesImport.TieImport toTieImport(IncludeKey includeKey, Thesaurus thesaurus, Label label, int weight) {
        return new InternalTieImport(includeKey, thesaurus, new InternalLabelOther(label), weight);
    }

    public static TiesImport.TieImport toTieImport(IncludeKey includeKey, Thesaurus thesaurus, String idalpha, int weight) {
        return new InternalTieImport(includeKey, thesaurus, new InternalIdalphaOther(idalpha), weight);
    }

    public static List<CorpusImport.FicheImport> wrap(CorpusImport.FicheImport[] array) {
        return new FicheImportList(array);
    }

    public static List<ThesaurusImport.MotcleImport> wrap(ThesaurusImport.MotcleImport[] array) {
        return new MotcleImportList(array);
    }

    public static ImportationContext toImportationContext(HtmlCleaner htmlCleaner, FichothequeQuestioner fichothequeQuestioner, HtmlConverter htmlConverter) {
        return new InternalImportationContext(htmlCleaner, fichothequeQuestioner, htmlConverter);
    }


    private static class InternalFicheImport implements CorpusImport.FicheImport {

        private final int ficheId;

        private InternalFicheImport(int ficheId) {
            this.ficheId = ficheId;
        }

        @Override
        public int getFicheId() {
            return ficheId;
        }

    }


    private static class InternalMotcleImport implements ThesaurusImport.MotcleImport {

        private final int motcleId;

        InternalMotcleImport(int motcleId) {
            this.motcleId = motcleId;
        }

        @Override
        public int getMotcleId() {
            return motcleId;
        }

    }


    private static class InternalTieImport implements TiesImport.TieImport {

        private final IncludeKey includeKey;
        private final Subset otherSubset;
        private final TiesImport.Other other;
        private final int weight;

        private InternalTieImport(IncludeKey includeKey, Subset otherSubset, TiesImport.Other other, int weight) {
            this.includeKey = includeKey;
            this.otherSubset = otherSubset;
            this.other = other;
            this.weight = weight;
        }

        @Override
        public IncludeKey getIncludeKey() {
            return includeKey;
        }

        @Override
        public Subset getOtherSubset() {
            return otherSubset;
        }

        @Override
        public int getWeight() {
            return weight;
        }

        @Override
        public TiesImport.Other getOther() {
            return other;
        }

    }


    private static class EmptyTiesImport implements TiesImport {

        private EmptyTiesImport() {

        }

        @Override
        public List<IncludeKey> getRemovedIncludeKeyList() {
            return FichothequeUtils.EMPTY_INCLUDEKEYLIST;
        }

        @Override
        public List<TieImport> getReplaceTieImportList() {
            return EMPTY_TIESIMPORTLIST;
        }

        @Override
        public List<TieImport> getAppendTieImportList() {
            return EMPTY_TIESIMPORTLIST;
        }

        @Override
        public boolean isEmpty() {
            return true;
        }

    }


    private static class InternalImportationContext implements ImportationContext {

        private final HtmlCleaner htmlCleaner;
        private final FichothequeQuestioner fichothequeQuestioner;
        private final HtmlConverter htmlConverter;

        private InternalImportationContext(HtmlCleaner htmlCleaner, FichothequeQuestioner fichothequeQuestioner, HtmlConverter htmlConverter) {
            this.htmlCleaner = htmlCleaner;
            this.fichothequeQuestioner = fichothequeQuestioner;
            this.htmlConverter = htmlConverter;
        }

        @Override
        public HtmlCleaner getHtmlCleaner() {
            return htmlCleaner;
        }

        @Override
        public FichothequeQuestioner getFichothequeQuestioner() {
            return fichothequeQuestioner;
        }

        @Override
        public HtmlConverter getHtmlConverter() {
            return htmlConverter;
        }

    }


    private static class FicheImportList extends AbstractList<CorpusImport.FicheImport> implements RandomAccess {

        private final CorpusImport.FicheImport[] array;

        private FicheImportList(CorpusImport.FicheImport[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public CorpusImport.FicheImport get(int index) {
            return array[index];
        }

    }


    private static class MotcleImportList extends AbstractList<ThesaurusImport.MotcleImport> implements RandomAccess {

        private final ThesaurusImport.MotcleImport[] array;

        private MotcleImportList(ThesaurusImport.MotcleImport[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public ThesaurusImport.MotcleImport get(int index) {
            return array[index];
        }

    }


    private static class InternalIdOther implements TiesImport.IdOther {

        private final int otherId;

        private InternalIdOther(int otherId) {
            this.otherId = otherId;
        }

        @Override
        public int getOtherId() {
            return otherId;
        }

    }


    private static class InternalLabelOther implements TiesImport.LabelOther {

        private final Label label;

        private InternalLabelOther(Label label) {
            this.label = label;
        }

        @Override
        public Label getLabel() {
            return label;
        }

    }


    private static class InternalIdalphaOther implements TiesImport.IdalphaOther {

        private final String idalpha;

        private InternalIdalphaOther(String idalpha) {
            this.idalpha = idalpha;
        }

        @Override
        public String getIdalpha() {
            return idalpha;
        }

    }

}
