/* BdfServer - 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 fr.exemole.bdfserver.tools.ficheform.builders;

import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ficheform.include.AddendaEntry;
import fr.exemole.bdfserver.api.ui.SubsetIncludeUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import java.util.Collection;
import java.util.List;
import net.fichotheque.SubsetKey;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.Document;
import net.fichotheque.junction.Liaison;
import net.fichotheque.include.ExtendedIncludeKey;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.utils.AddendaUtils;
import net.fichotheque.utils.JunctionUtils;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.Attributes;


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

    private final String name;
    private final Addenda addenda;
    private String label = "";
    private boolean mandatory = false;
    private boolean addAllowed = false;
    private Collection<Liaison> liaisons = JunctionUtils.EMPTY_LIAISONLIST;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;

    public AddendaEntryBuilder(String name, Addenda addenda) {
        this.name = name;
        this.addenda = addenda;
    }

    public AddendaEntryBuilder setLabel(String label) {
        if (label == null) {
            throw new IllegalArgumentException("label is null");
        }
        this.label = label;
        return this;
    }

    public AddendaEntryBuilder setMandatory(boolean mandatory) {
        this.mandatory = mandatory;
        return this;
    }

    public AddendaEntryBuilder setLiaisons(Collection<Liaison> liaisons) {
        if (liaisons == null) {
            this.liaisons = JunctionUtils.EMPTY_LIAISONLIST;
        } else {
            this.liaisons = liaisons;
        }
        return this;
    }

    public AddendaEntryBuilder setAttributes(Attributes attributes) {
        if (attributes == null) {
            this.attributes = AttributeUtils.EMPTY_ATTRIBUTES;
        } else {
            this.attributes = attributes;
        }
        return this;
    }

    public AddendaEntryBuilder setAddAllowed(boolean addAllowed) {
        this.addAllowed = addAllowed;
        return this;
    }

    public AddendaEntry toAddendaEntry() {
        int size = liaisons.size();
        Document[] documentArray = new Document[size];
        int p = 0;
        for (Liaison liaison : liaisons) {
            documentArray[p] = (Document) liaison.getSubsetItem();
            p++;
        }
        return new InternalAddendaEntry(name, addenda, label, mandatory, attributes, AddendaUtils.wrap(documentArray), addAllowed);
    }

    @Nullable
    public static AddendaEntryBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, SubsetIncludeUi includeUi) {
        ExtendedIncludeKey includeKey = includeUi.getExtendedIncludeKey();
        SubsetKey addendaKey = includeKey.getSubsetKey();
        Addenda addenda = (Addenda) ficheFormParameters.getBdfServer().getFichotheque().getSubset(addendaKey);
        if (addenda == null) {
            return null;
        }
        boolean addAllowed = ficheFormParameters.getPermissionSummary().isSubsetAdmin(addendaKey);
        Collection<Liaison> liaisons = fichePointeur.getLiaisons(addenda, includeKey);
        if ((liaisons.isEmpty()) && (includeUi.isObsolete())) {
            return null;
        }
        return init(includeUi.getName(), addenda)
                .setLiaisons(liaisons)
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, includeUi))
                .setAddAllowed(addAllowed)
                .setAttributes(includeUi.getAttributes());
    }

    public static AddendaEntryBuilder init(String name, Addenda addenda) {
        return new AddendaEntryBuilder(name, addenda);
    }


    private static class InternalAddendaEntry implements AddendaEntry {

        private final String name;
        private final Addenda addenda;
        private final String label;
        private final boolean mandatory;
        private final boolean addAllowed;
        private final Attributes attributes;
        private final List<Document> documentList;

        private InternalAddendaEntry(String name, Addenda addenda, String label, boolean mandatory, Attributes attributes, List<Document> documentList, boolean addAllowed) {
            this.name = name;
            this.addenda = addenda;
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.documentList = documentList;
            this.addAllowed = addAllowed;
        }

        @Override
        public String getIncludeName() {
            return name;
        }

        @Override
        public Addenda getAddenda() {
            return addenda;
        }

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

        @Override
        public boolean isMandatory() {
            return mandatory;
        }

        @Override
        public Attributes getAttributes() {
            return attributes;
        }

        @Override
        public boolean isAddAllowed() {
            return addAllowed;
        }

        @Override
        public List<Document> getDocumentList() {
            return documentList;
        }

    }

}
