/* FichothequeLib_Tools - Copyright (c) 2016-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 net.fichotheque.tools.format;

import java.time.format.FormatStyle;
import java.util.HashSet;
import java.util.Set;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.date.DateConstants;
import net.mapeadores.util.instruction.Argument;
import net.mapeadores.util.instruction.Instruction;
import net.mapeadores.util.json.PropertyEligibility;
import net.mapeadores.util.text.StringUtils;


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

    private final InternalPropertyEligibility internalPropertyEligibility = new InternalPropertyEligibility();
    private final Set<String> propertyNameSet;
    private final String cellConverterName;
    private final FormatStyle formatStyle;

    public JsonParameters(Set<String> propertyNameSet, String cellConverterName, FormatStyle formatStyle) {
        this.propertyNameSet = propertyNameSet;
        this.cellConverterName = cellConverterName;
        this.formatStyle = formatStyle;
    }

    public PropertyEligibility getPropertyEligibility() {
        return internalPropertyEligibility;
    }


    @Nullable
    public String getCellConverterName() {
        return cellConverterName;
    }

    @Nullable
    public FormatStyle getFormatStyle() {
        return formatStyle;
    }

    public static JsonParameters fromInstruction(Instruction instruction, JsonParameters defaultJsonParameters) {
        Set<String> propertyNameSet = new HashSet<String>(defaultJsonParameters.propertyNameSet);
        String cellConverterName = defaultJsonParameters.getCellConverterName();
        FormatStyle formatStyle = defaultJsonParameters.getFormatStyle();
        for (Argument argument : instruction) {
            String key = argument.getKey();
            String value = argument.getNotNullValue();
            switch (key) {
                case "include": {
                    String[] tokens = StringUtils.getTechnicalTokens(value, true);
                    for (String token : tokens) {
                        if (token.startsWith("-")) {
                            propertyNameSet.remove(token.substring(1));
                        } else {
                            propertyNameSet.add(token);
                        }
                    }
                    break;
                }
                case "properties":
                case "cells": {
                    if (!value.isEmpty()) {
                        cellConverterName = value;
                    }
                    break;
                }
                case "datestyle": {
                    formatStyle = DateConstants.getMatchingFormatStyle(value);
                    break;
                }
            }
        }
        return new JsonParameters(propertyNameSet, cellConverterName, formatStyle);
    }

    public static JsonParameters build(String... propertyNames) {
        Set<String> propertyNameSet = new HashSet<String>();
        for (String propertyName : propertyNames) {
            propertyNameSet.add(propertyName);
        }
        return new JsonParameters(propertyNameSet, null, null);
    }


    private class InternalPropertyEligibility implements PropertyEligibility {

        private InternalPropertyEligibility() {

        }

        @Override
        public boolean includeProperty(String propertyName) {
            if (propertyName.equals("properties")) {
                return (cellConverterName != null);
            }
            return propertyNameSet.contains(propertyName);
        }

    }

}
