/* 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.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.LiensImport;
import net.fichotheque.importation.ThesaurusImport;
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 LiensImport EMPTY_LIENSIMPORT = new EmptyLiensImport();
    public final static List<LiensImport.LienImport> EMPTY_LIENIMPORTLIST = 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 LiensImport.LienImport toLienImport(IncludeKey originIncludeKey, SubsetItem otherSubsetItem, int weight) {
        return new InternalLienImport(originIncludeKey, otherSubsetItem.getSubset(), new InternalIdOther(otherSubsetItem.getId()), weight);
    }

    public static LiensImport.LienImport toLienImport(IncludeKey originIncludeKey, Thesaurus thesaurus, Label label, int weight) {
        return new InternalLienImport(originIncludeKey, thesaurus, new InternalLabelOther(label), weight);
    }

    public static LiensImport.LienImport toLienImport(IncludeKey originIncludeKey, Thesaurus thesaurus, String idalpha, int weight) {
        return new InternalLienImport(originIncludeKey, thesaurus, new InternalIdalphaOther(idalpha), weight);
    }

    public static LiensImport.LienImport toLiageLienImport(SubsetItem otherSubsetItem, int weight) {
        return new InternalLienImport(null, otherSubsetItem.getSubset(), new InternalIdOther(otherSubsetItem.getId()), 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, HtmlConverter htmlConverter) {
        return new InternalImportationContext(htmlCleaner, 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 InternalLienImport implements LiensImport.LienImport {

        private final IncludeKey originIncludeKey;
        private final Subset otherSubset;
        private final LiensImport.Other other;
        private final int weight;
        private final Label label;

        private InternalLienImport(IncludeKey originIncludeKey, Subset otherSubset, LiensImport.Other other, int weight) {
            this.originIncludeKey = originIncludeKey;
            this.otherSubset = otherSubset;
            this.other = other;
            this.weight = weight;
            this.label = null;
        }

        @Override
        public IncludeKey getOriginIncludeKey() {
            return originIncludeKey;
        }

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

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

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

    }


    private static class EmptyLiensImport implements LiensImport {

        private EmptyLiensImport() {

        }

        @Override
        public boolean isLiageRemoved() {
            return false;
        }

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

        @Override
        public List<LienImport> getReplaceLienImportList() {
            return EMPTY_LIENIMPORTLIST;
        }

        @Override
        public List<LienImport> getAppendLienImportList() {
            return EMPTY_LIENIMPORTLIST;
        }

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

    }


    private static class InternalImportationContext implements ImportationContext {

        private final HtmlCleaner htmlCleaner;
        private final HtmlConverter htmlConverter;

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

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

        @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 LiensImport.IdOther {

        private final int otherId;

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

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

    }


    private static class InternalLabelOther implements LiensImport.LabelOther {

        private final Label label;

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

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

    }


    private static class InternalIdalphaOther implements LiensImport.IdalphaOther {

        private final String idalpha;

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

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

    }

}
