/* FichothequeLib_API - Copyright (c) 2019-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.utils;

import java.util.AbstractList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
import java.util.Set;
import java.util.function.Predicate;
import net.fichotheque.Fichotheque;
import net.fichotheque.FichothequeQuestioner;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.extraction.DataResolverProvider;
import net.fichotheque.extraction.ExtractParameters;
import net.fichotheque.extraction.ExtractionConstants;
import net.fichotheque.extraction.ExtractionContext;
import net.fichotheque.extraction.FilterParameters;
import net.fichotheque.extraction.IrefConverter;
import net.fichotheque.extraction.LinkAnalyser;
import net.fichotheque.extraction.SyntaxResolver;
import net.fichotheque.extraction.filterunit.FilterUnit;
import net.fichotheque.extraction.run.CorpusExtractResult;
import net.fichotheque.extraction.run.ExtractorProvider;
import net.fichotheque.extraction.run.ThesaurusExtractResult;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.thesaurus.policies.PolicyProvider;
import net.mapeadores.util.localisation.LangContext;
import net.mapeadores.util.localisation.MessageLocalisationProvider;
import net.mapeadores.util.mimetype.MimeTypeResolver;
import net.mapeadores.util.text.StringUtils;


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

    public final static FilterParameters EMPTY_FILTERPARAMETERS = new EmptyFilterParameters();
    public final static List<CorpusExtractResult> EMPTY_CORPUSEXTRACTRESULTLIST = Collections.emptyList();
    public final static List<ThesaurusExtractResult> EMPTY_THESAURUSEXTRACTRESULTLIST = Collections.emptyList();
    public final static List<FilterUnit> EMPTY_FILTERUNITLIST = Collections.emptyList();
    public final static IrefConverter SAME_CONVERTER = new SameIrefConverter();


    private ExtractionUtils() {

    }

    public static int parseExtractVersion(String text) {
        if (text == null) {
            return ExtractionConstants.INITIAL_VERSION;
        }
        try {
            int value = Integer.parseInt(text);
            switch (value) {
                case ExtractionConstants.INITIAL_VERSION:
                case ExtractionConstants.PLURAL_VERSION:
                case ExtractionConstants.INTERNATIONAL_VERSION:
                    return value;
            }
        } catch (NumberFormatException nfe) {

        }
        return ExtractionConstants.INTERNATIONAL_VERSION;
    }

    public static String checkSort(String sort) {
        if ((sort == null) || (sort.length() == 0)) {
            return ExtractionConstants.ASCENDING_SORT;
        }
        switch (sort) {
            case ExtractionConstants.DESCENDING_SORT:
                return ExtractionConstants.DESCENDING_SORT;
            default:
                return ExtractionConstants.ASCENDING_SORT;
        }
    }

    public static String checkType(String type) {
        if ((type == null) || (type.length() == 0)) {
            throw new IllegalArgumentException("undefined type");
        }
        switch (type) {
            case ExtractionConstants.WEIGHT_TYPE:
            case "poids":
                return ExtractionConstants.WEIGHT_TYPE;
            case ExtractionConstants.TITLE_TYPE:
            case "titre":
                return ExtractionConstants.TITLE_TYPE;
            case ExtractionConstants.YEAR_TYPE:
            case "annee":
                return ExtractionConstants.YEAR_TYPE;
            case ExtractionConstants.LANG_TYPE:
                return ExtractionConstants.LANG_TYPE;
            case ExtractionConstants.COUNTRY_TYPE:
            case "pays":
                return ExtractionConstants.COUNTRY_TYPE;
            case ExtractionConstants.FIELDS_TYPE:
                return ExtractionConstants.FIELDS_TYPE;
            case ExtractionConstants.POSITION_TYPE:
                return ExtractionConstants.POSITION_TYPE;
            default:
                throw new IllegalArgumentException("unknwon type : " + type);
        }
    }

    public static ExtractionContext derive(ExtractionContext extractionContext, LangContext langContext) {
        return new DeriveExtractionContext(extractionContext, langContext);
    }

    public static List<FilterUnit> toImmutableList(Collection<FilterUnit> collection) {
        int size = collection.size();
        if (size == 0) {
            return EMPTY_FILTERUNITLIST;
        }
        return new FilterUnitList(collection.toArray(new FilterUnit[size]));
    }

    public static List<FilterUnit> wrap(FilterUnit[] array) {
        return new FilterUnitList(array);
    }

    public static ExtractParameters derive(ExtractParameters extractParameters, Predicate<FicheMeta> fichePredicate) {
        return new DeriveExtractParameters(extractParameters, fichePredicate);
    }


    private static class DeriveExtractionContext implements ExtractionContext {

        private final ExtractionContext originExtractionContext;
        private final LangContext langContext;

        private DeriveExtractionContext(ExtractionContext originExtractionContext, LangContext langContext) {
            this.originExtractionContext = originExtractionContext;
            this.langContext = langContext;
        }

        @Override
        public Fichotheque getFichotheque() {
            return originExtractionContext.getFichotheque();
        }

        @Override
        public FichothequeQuestioner getFichothequeQuestioner() {
            return originExtractionContext.getFichothequeQuestioner();
        }

        @Override
        public MessageLocalisationProvider getMessageLocalisationProvider() {
            return originExtractionContext.getMessageLocalisationProvider();
        }

        @Override
        public LangContext getLangContext() {
            return langContext;
        }

        @Override
        public LinkAnalyser getLinkAnalyser() {
            return originExtractionContext.getLinkAnalyser();
        }

        @Override
        public ExtractorProvider getExtractorProvider() {
            return originExtractionContext.getExtractorProvider();
        }

        @Override
        public MimeTypeResolver getMimeTypeResolver() {
            return originExtractionContext.getMimeTypeResolver();
        }

        @Override
        public SyntaxResolver getSyntaxResolver() {
            return originExtractionContext.getSyntaxResolver();
        }

        @Override
        public PermissionSummary getPermissionSummary() {
            return originExtractionContext.getPermissionSummary();
        }

        @Override
        public DataResolverProvider getDataResolverProvider() {
            return originExtractionContext.getDataResolverProvider();
        }

        @Override
        public PolicyProvider getPolicyProvider() {
            return originExtractionContext.getPolicyProvider();
        }

    }


    private static class DeriveExtractParameters implements ExtractParameters {

        private final ExtractParameters originalExtractParameters;
        private final Predicate<FicheMeta> fichePredicate;

        private DeriveExtractParameters(ExtractParameters originalExtractParameters, Predicate<FicheMeta> fichePredicate) {
            this.originalExtractParameters = originalExtractParameters;
            this.fichePredicate = fichePredicate;
        }

        @Override
        public ExtractionContext getExtractionContext() {
            return originalExtractParameters.getExtractionContext();
        }

        @Override
        public int getExtractVersion() {
            return originalExtractParameters.getExtractVersion();
        }

        @Override
        public boolean isWithEmpty() {
            return originalExtractParameters.isWithEmpty();
        }

        @Override
        public Predicate<FicheMeta> getFichePredicate() {
            return fichePredicate;
        }

        @Override
        public IrefConverter newIrefConverter() {
            return originalExtractParameters.newIrefConverter();
        }

        @Override
        public boolean isWithPosition() {
            return originalExtractParameters.isWithPosition();
        }

    }


    private static class EmptyFilterParameters implements FilterParameters {


        private EmptyFilterParameters() {

        }

        @Override
        public Set<String> getParameterNameSet() {
            return StringUtils.EMPTY_STRINGSET;
        }

        @Override
        public List<String> getParameter(String name) {
            return StringUtils.EMPTY_STRINGLIST;
        }


    }


    private static class FilterUnitList extends AbstractList<FilterUnit> implements RandomAccess {

        private final FilterUnit[] array;

        private FilterUnitList(FilterUnit[] array) {
            this.array = array;
        }

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

        @Override
        public FilterUnit get(int index) {
            return array[index];
        }

    }


    private static class SameIrefConverter implements IrefConverter {

        private SameIrefConverter() {

        }

        @Override
        public String convert(String ref) {
            return ref;
        }

    }


}
