/* FichothequeLib_Tools - Copyright (c) 2016-2018 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.selection;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.selection.PeriodCondition;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.mapeadores.util.primitives.FuzzyDate;


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

    private String startType = PeriodCondition.ANY_TYPE;
    private FuzzyDate startDate = null;
    private String endType = PeriodCondition.SAME_TYPE;
    private FuzzyDate endDate = null;
    private boolean onCreationDate = false;
    private boolean onModificationDate = false;
    private final Set<FieldKey> fieldKeySet = new LinkedHashSet<FieldKey>();

    public PeriodConditionBuilder() {

    }

    public PeriodConditionBuilder setAnyStartDate() {
        this.startType = PeriodCondition.ANY_TYPE;
        this.startDate = null;
        return this;
    }

    public PeriodConditionBuilder setStartDate(FuzzyDate startDate) {
        if (startDate == null) {
            throw new IllegalArgumentException("startDate is null");
        }
        this.startType = PeriodCondition.DATE_TYPE;
        this.startDate = startDate;
        return this;
    }

    public PeriodConditionBuilder setAnyEndDate() {
        this.endType = PeriodCondition.ANY_TYPE;
        this.endDate = null;
        return this;
    }

    public PeriodConditionBuilder setSameEndDate() {
        this.endType = PeriodCondition.SAME_TYPE;
        this.endDate = null;
        return this;
    }

    public PeriodConditionBuilder setEndDate(FuzzyDate endDate) {
        if (endDate == null) {
            throw new IllegalArgumentException("endDate is null");
        }
        this.endType = PeriodCondition.DATE_TYPE;
        this.endDate = endDate;
        return this;
    }

    public PeriodConditionBuilder setOnCreationDate(boolean onCreationDate) {
        this.onCreationDate = onCreationDate;
        return this;
    }

    public PeriodConditionBuilder setOnModificationDate(boolean onModificationDate) {
        this.onModificationDate = onModificationDate;
        return this;
    }

    public PeriodConditionBuilder addFieldKey(FieldKey fieldKey) {
        fieldKeySet.add(fieldKey);
        return this;
    }

    public PeriodConditionBuilder addFieldKeys(Collection<FieldKey> fieldKeys) {
        fieldKeySet.addAll(fieldKeys);
        return this;
    }

    public PeriodCondition toPeriodCondition() {
        List<FieldKey> fieldKeyList;
        if (fieldKeySet.isEmpty()) {
            fieldKeyList = CorpusMetadataUtils.EMPTY_FIELDKEYLIST;
        } else {
            fieldKeyList = CorpusMetadataUtils.wrap(fieldKeySet.toArray(new FieldKey[fieldKeySet.size()]));
        }
        return new InternalPeriodCondition(startType, startDate, endType, endDate, onCreationDate, onModificationDate, fieldKeyList);
    }

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


    private static class InternalPeriodCondition implements PeriodCondition {

        private final String startType;
        private final FuzzyDate startDate;
        private final String endType;
        private final FuzzyDate endDate;
        private final boolean onCreationDate;
        private final boolean onModificationDate;
        private final List<FieldKey> fieldKeyList;

        private InternalPeriodCondition(String startType, FuzzyDate startDate, String endType, FuzzyDate endDate, boolean onCreationDate, boolean onModificationDate, List<FieldKey> fieldKeyList) {
            this.startType = startType;
            this.startDate = startDate;
            this.endType = endType;
            this.endDate = endDate;
            this.onCreationDate = onCreationDate;
            this.onModificationDate = onModificationDate;
            this.fieldKeyList = fieldKeyList;
        }

        @Override
        public String getStartType() {
            return startType;
        }

        @Override
        public FuzzyDate getStartDate() {
            return startDate;
        }

        @Override
        public String getEndType() {
            return endType;
        }

        @Override
        public FuzzyDate getEndDate() {
            return endDate;
        }

        @Override
        public boolean isOnCreationDate() {
            return onCreationDate;
        }

        @Override
        public boolean isOnModificationDate() {
            return onModificationDate;
        }

        @Override
        public List<FieldKey> getFieldKeyList() {
            return fieldKeyList;
        }

    }

}
