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

import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import java.text.ParseException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.fichotheque.corpus.metadata.FieldKey;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.text.StringUtils;


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

    public final static String TABLEEXPORT_TYPE = "tableexport";
    public final static String SPECIAL_TYPE = "special";
    public final static String COMPONENTS_TYPE = "components";
    public final static String EMPTY_SPECIAL = "empty";
    public final static String TABLE_SPECIAL = "table";
    public final static String FORM_SPECIAL = "form";
    public final static String PHRASES_SPECIAL = "phrases";
    public final static String USERDEFAULT_SPECIAL = "userdefault";
    public final static PropertiesParam EMPTY;
    public final static PropertiesParam TABLE;
    public final static PropertiesParam FORM;
    public final static PropertiesParam PHRASES;
    public final static PropertiesParam USERDEFAULT;
    private final String type;
    private final String name;
    private final List<String> componentNameList;

    static {
        EMPTY = new PropertiesParam(SPECIAL_TYPE, EMPTY_SPECIAL);
        TABLE = new PropertiesParam(SPECIAL_TYPE, TABLE_SPECIAL);
        FORM = new PropertiesParam(SPECIAL_TYPE, FORM_SPECIAL);
        PHRASES = new PropertiesParam(SPECIAL_TYPE, PHRASES_SPECIAL);
        USERDEFAULT = new PropertiesParam(SPECIAL_TYPE, USERDEFAULT_SPECIAL);
    }

    private PropertiesParam(String type, String name) {
        this.type = type;
        this.name = name;
        this.componentNameList = null;
    }

    private PropertiesParam(String type, String name, List<String> componentNameList) {
        this.type = type;
        this.name = name;
        this.componentNameList = componentNameList;
    }

    public String getType() {
        return type;
    }

    public String getName() {
        return name;
    }

    public String getCompleteString() {
        return type + ":" + name;
    }

    public List<String> getComponentNameList() {
        return componentNameList;
    }

    public boolean isTableExport() {
        return (type.equals(TABLEEXPORT_TYPE));
    }

    public boolean isSpecial() {
        return (type.equals(SPECIAL_TYPE));
    }

    public static boolean hasPropertiesParam(RequestMap requestMap) {
        PropertiesParam propertiesParam = fromRequest(requestMap, null);
        return (propertiesParam != null);
    }

    public static PropertiesParam fromRequest(RequestMap requestMap) {
        return fromRequest(requestMap, EMPTY);
    }

    public static PropertiesParam fromRequest(RequestMap requestMap, PropertiesParam defaultPropertiesParam) {
        PropertiesParam propertiesParam = fromRequest(requestMap, InteractionConstants.PROPERTIES_PARAMNAME, InteractionConstants.TABLEEXPORT_PARAMNAME);
        if (propertiesParam == null) {
            propertiesParam = defaultPropertiesParam;
        }
        return propertiesParam;
    }

    public static PropertiesParam fromRequest(RequestMap requestMap, String propertiesParamName, String tableExportParamName) {
        if (propertiesParamName != null) {
            PropertiesParam propertiesParam = fromProperties(requestMap.getTrimedParameter(propertiesParamName));
            if (propertiesParam != null) {
                return propertiesParam;
            }
        }
        if (tableExportParamName != null) {
            PropertiesParam propertiesParam = fromTableExport(requestMap.getTrimedParameter(tableExportParamName));
            if (propertiesParam != null) {
                return propertiesParam;
            }
        }
        return null;
    }

    private static PropertiesParam fromProperties(String properties) {
        int idx = properties.indexOf(":");
        if (idx > 1) {
            String type = properties.substring(0, idx);
            String value = properties.substring(idx + 1);
            switch (type) {
                case SPECIAL_TYPE: {
                    switch (properties) {
                        case EMPTY_SPECIAL:
                            return EMPTY;
                        case TABLE_SPECIAL:
                            return TABLE;
                        case FORM_SPECIAL:
                            return FORM;
                        case PHRASES_SPECIAL:
                            return PHRASES;
                        case USERDEFAULT_SPECIAL:
                        case "default":
                            return USERDEFAULT;
                        default:
                            return new PropertiesParam(SPECIAL_TYPE, value);
                    }
                }
                case TABLEEXPORT_TYPE: {
                    return fromTableExport(value);
                }
                case COMPONENTS_TYPE: {
                    return fromComponents(value);
                }
            }
        }
        return null;
    }

    private static PropertiesParam fromTableExport(String tableExportName) {
        if (!tableExportName.isEmpty()) {
            switch (tableExportName) {
                case "_table":
                    return TABLE;
                case "_form":
                    return FORM;
                case "_default":
                case "_userdefault":
                    return USERDEFAULT;
                default:
                    return new PropertiesParam(TABLEEXPORT_TYPE, tableExportName);
            }
        }
        return null;
    }

    private static PropertiesParam fromComponents(String componentsString) {
        Set<String> componentNameSet = new LinkedHashSet<String>();
        String[] tokens = StringUtils.getTechnicalTokens(componentsString, true);
        for (String token : tokens) {
            try {
                FieldKey fieldKey = FieldKey.parse(token);
                token = fieldKey.getKeyString();
            } catch (ParseException pe) {

            }
            componentNameSet.add(token);
        }
        return new PropertiesParam(COMPONENTS_TYPE, componentsString, StringUtils.toList(componentNameSet));
    }

}
