/* FichothequeLib_Tools - Copyright (c) 2010-2023 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.extraction.builders;

import java.util.ArrayList;
import java.util.List;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.extraction.ExtractionConstants;
import net.fichotheque.extraction.def.FicheFilter;
import net.fichotheque.extraction.def.TagNameInfo;
import net.fichotheque.extraction.filterunit.FieldKeyFilterUnit;
import net.fichotheque.extraction.filterunit.FieldNamePrefixFilterUnit;
import net.fichotheque.extraction.filterunit.FilterUnit;
import net.fichotheque.utils.ExtractionUtils;
import net.fichotheque.extraction.filterunit.BodyFilterUnit;


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

    private final List<FilterUnit> filterUnitList = new ArrayList<FilterUnit>();
    private TagNameInfo tagNameInfo = TagNameInfo.DEFAULT;

    public FicheFilterBuilder() {
    }


    public FicheFilterBuilder add(FilterUnit filterUnit) {
        if (filterUnit == null) {
            throw new NullPointerException("filterUnit is null");
        }
        filterUnitList.add(filterUnit);
        return this;
    }

    public FicheFilterBuilder setTagNameInfo(TagNameInfo tagNameInfo) {
        this.tagNameInfo = tagNameInfo;
        return this;
    }

    private boolean testCorpsdefiche(short category) {
        switch (category) {
            case FieldKey.SECTION_CATEGORY:
                return true;
            default:
                return false;
        }
    }

    public FicheFilter toFicheFilter() {
        boolean withCorpsdefiche = false;
        int cellMax = -1;
        for (FilterUnit filterUnit : filterUnitList) {
            if (filterUnit instanceof BodyFilterUnit) {
                withCorpsdefiche = true;
            } else if (filterUnit instanceof FieldKeyFilterUnit) {
                boolean test = testCorpsdefiche(((FieldKeyFilterUnit) filterUnit).getFieldKey().getCategory());
                if (test) {
                    withCorpsdefiche = true;
                }
            } else if (filterUnit instanceof FieldNamePrefixFilterUnit) {
                boolean test = testCorpsdefiche(((FieldNamePrefixFilterUnit) filterUnit).getCategory());
                if (test) {
                    withCorpsdefiche = true;
                }
            }
            int cellValue = filterUnit.getIntValue(ExtractionConstants.CELL_ORDER_PARAM);
            if (cellValue > 0) {
                cellMax = Math.max(cellMax, cellValue);
            }
        }
        List<FilterUnit> finalFilterUnitList = ExtractionUtils.toImmutableList(filterUnitList);
        return new InternalFicheFilter(tagNameInfo, finalFilterUnitList, withCorpsdefiche, cellMax);
    }

    public static FicheFilterBuilder init() {
        return new FicheFilterBuilder();
    }


    private static class InternalFicheFilter implements FicheFilter {

        private final TagNameInfo tagNameInfo;
        private final List<FilterUnit> filterUnitList;
        private final boolean withCorpsdefiche;
        private final int cellMax;


        private InternalFicheFilter(TagNameInfo tagNameInfo, List<FilterUnit> filterUnitList, boolean withCorpsdefiche, int cellMax) {
            this.tagNameInfo = tagNameInfo;
            this.filterUnitList = filterUnitList;
            this.withCorpsdefiche = withCorpsdefiche;
            this.cellMax = cellMax;
        }

        @Override
        public TagNameInfo getTagNameInfo() {
            return tagNameInfo;
        }

        @Override
        public boolean isWithCorpsdefiche() {
            return withCorpsdefiche;
        }

        @Override
        public List<FilterUnit> getFilterUnitList() {
            return filterUnitList;
        }

        @Override
        public int getCellMax() {
            return cellMax;
        }

    }


}
