/* BdfServer - Copyright (c) 2024 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.exportation.transformation;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.exportation.transformation.TransformationConstants;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.namespaces.BdfUserSpace;
import fr.exemole.bdfserver.api.users.BdfUser;
import fr.exemole.bdfserver.tools.users.BdfUserUtils;
import java.util.HashMap;
import java.util.Map;
import net.fichotheque.namespaces.TransformationSpace;
import net.fichotheque.sphere.Redacteur;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.attr.AttributeKey;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.localisation.Lang;


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

    private final Map<String, Object> map = new HashMap<String, Object>();

    public TransformerParameters() {

    }

    public TransformerParameters put(String name, Object value) {
        map.put(name, value);
        return this;
    }

    public TransformerParameters putAll(Map<String, Object> otherMap) {
        map.putAll(otherMap);
        return this;
    }

    public TransformerParameters check(Attributes attributes) {
        checkIncludeScripts(attributes);
        checkTextParameters(attributes, TransformationConstants.TEXT_FIELDBULLET_PARAMETER);
        checkTextParameters(attributes, TransformationConstants.TEXT_SECTIONEND_PARAMETER);
        checkWithParameters(attributes, TransformationConstants.WITH_FICHENUMBER_PARAMETER);
        checkWithParameters(attributes, TransformationConstants.WITH_RESOURCELOGO_PARAMETER);
        return this;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    private void checkIncludeScripts(Attributes attributes) {
        Attribute attribute = attributes.getAttribute(BdfUserSpace.INCLUDESCRIPTS_KEY);
        if (attribute == null) {
            return;
        }
        String includeScripts = "";
        int size = attribute.size();
        if (size == 1) {
            includeScripts = attribute.getFirstValue();
        } else {
            StringBuilder buf = new StringBuilder();
            for (String value : attribute) {
                if (buf.length() > 0) {
                    buf.append(' ');
                }
                buf.append(value);
            }
            includeScripts = buf.toString();
        }
        map.put(TransformationConstants.INCLUDESCRIPTS_PARAMETER, includeScripts);
    }

    private void checkTextParameters(Attributes attributes, String name) {
        AttributeKey matchingKey = getMatchingAttributeKey(name);
        if (matchingKey == null) {
            return;
        }
        Attribute attribute = attributes.getAttribute(matchingKey);
        if (attribute == null) {
            return;
        }
        String value = attribute.getFirstValue();
        int length = value.length();
        if (length == 1) {
            if (value.charAt('0') == '\'') {
                value = "";
            }
        } else {
            if (value.charAt(length - 1) == '\'') {
                value = value.substring(0, length - 1);
            }
            if (value.charAt(0) == '\'') {
                value = value.substring(1);
            }
        }
        map.put(name, value);
    }

    private void checkWithParameters(Attributes attributes, String name) {
        AttributeKey matchingKey = getMatchingAttributeKey(name);
        if (matchingKey == null) {
            return;
        }
        Attribute attribute = attributes.getAttribute(matchingKey);
        if (attribute == null) {
            return;
        }
        map.put(name, attribute.getFirstValue());
    }

    public static TransformerParameters build(BdfParameters bdfParameters) {
        BdfServer bdfServer = bdfParameters.getBdfServer();
        BdfUser bdfUser = bdfParameters.getBdfUser();
        Redacteur redacteur = bdfUser.getRedacteur();
        boolean hideEmpty = bdfUser.getPrefs().getBoolean(BdfUserSpace.HIDEEMPTY_KEY);
        TransformerParameters transformerParameters = new TransformerParameters();
        transformerParameters
                .put(TransformationConstants.WORKINGLANG_PARAMETER, bdfUser.getWorkingLang().toString())
                .put(TransformationConstants.BDF_VERSION_PARAMETER, bdfServer.getBuildInfo().getVersion())
                .put(TransformationConstants.BDF_FICHOTHEQUEPATH_PARAMETER, BdfUserUtils.getRootUrl(bdfUser))
                .put(TransformationConstants.SHOWEMPTY_PARAMETER, (hideEmpty) ? 0 : 1)
                .put(TransformationConstants.USER_SPHERE_PARAMETER, redacteur.getSubsetName())
                .put(TransformationConstants.USER_LOGIN_PARAMETER, redacteur.getLogin())
                .check(bdfServer.getFichotheque().getFichothequeMetadata().getAttributes());
        return transformerParameters;
    }

    public static TransformerParameters build(Lang workingLang) {
        TransformerParameters transformerParameters = new TransformerParameters();
        transformerParameters
                .put(TransformationConstants.WORKINGLANG_PARAMETER, workingLang.toString());
        return transformerParameters;
    }

    private static AttributeKey getMatchingAttributeKey(String name) {
        switch (name) {
            case TransformationConstants.TEXT_FIELDBULLET_PARAMETER:
                return TransformationSpace.FIELDBULLET_KEY;
            case TransformationConstants.TEXT_SECTIONEND_PARAMETER:
                return TransformationSpace.SECTIONEND_KEY;
            case TransformationConstants.WITH_FICHENUMBER_PARAMETER:
                return TransformationSpace.FICHENUMBER_KEY;
            case TransformationConstants.WITH_RESOURCELOGO_PARAMETER:
                return TransformationSpace.RESOURCELOGO_KEY;
            default:
                return null;
        }
    }

}
