/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.freemarker.core;

import org.apache.freemarker.core.cformat.impl.StandardCFormats;
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateStringModel;
import org.apache.freemarker.core.util._SortedArraySet;
import org.apache.freemarker.core.util._StringUtils;

import java.util.Set;

/**
 * AST directive node: {@code #setting}.
 */
final class ASTDirSetting extends ASTDirective {

    private final String key;
    private final ASTExpression value;

    private final ValueSafetyChecker valueSafeyChecker;

    static final Set<String> SETTING_NAMES = new _SortedArraySet<>(
            // Must be sorted alphabetically!
            MutableProcessingConfiguration.BOOLEAN_FORMAT_KEY,
            MutableProcessingConfiguration.C_FORMAT_KEY,
            MutableProcessingConfiguration.DATE_FORMAT_KEY,
            MutableProcessingConfiguration.DATE_TIME_FORMAT_KEY,
            MutableProcessingConfiguration.LOCALE_KEY,
            MutableProcessingConfiguration.NUMBER_FORMAT_KEY,
            MutableProcessingConfiguration.OUTPUT_ENCODING_KEY,
            MutableProcessingConfiguration.SQL_DATE_AND_TIME_TIME_ZONE_KEY,
            MutableProcessingConfiguration.TIME_FORMAT_KEY,
            MutableProcessingConfiguration.TIME_ZONE_KEY,
            MutableProcessingConfiguration.URL_ESCAPING_CHARSET_KEY
    );

    ASTDirSetting(Token keyTk, FMParserTokenManager tokenManager, ASTExpression value, Configuration cfg)
            throws ParseException {
        String key = keyTk.image;
        if (!SETTING_NAMES.contains(key)) {
            StringBuilder sb = new StringBuilder();
            if (Configuration.ExtendableBuilder.getSettingNames().contains(key)) {
                sb.append("The setting name is recognized, but changing this setting from inside a template isn't "
                        + "supported.");                
            } else {
                sb.append("Unknown setting name: ");
                sb.append(_StringUtils.jQuote(key)).append(".");

                String correctedKey;
                if (key.indexOf('_') != -1) {
                    sb.append(MessageUtils.FM3_SNAKE_CASE);
                    correctedKey = _StringUtils.snakeCaseToCamelCase(key);
                    if (!SETTING_NAMES.contains(correctedKey)) {
                        if (key.equals("datetime_format")) {
                            correctedKey = "dateTimeFormat";
                        } else {
                            correctedKey = null;
                        }
                    }
                } else if (key.equals("datetimeFormat")) {
                    correctedKey = "dateTimeFormat";
                } else {
                    correctedKey = null;
                }

                if (correctedKey != null) {
                    sb.append("\nThe correct name is: ").append(correctedKey);
                } else {
                    sb.append("\nThe allowed setting names are: ");

                    boolean first = true;
                    for (String correctName : SETTING_NAMES) {
                        if (first) {
                            first = false;
                        } else {
                            sb.append(", ");
                        }

                        sb.append(correctName);
                    }
                }
            }
            throw new ParseException(sb.toString(), null, keyTk);
        }
        
        this.key = key;
        this.value = value;

        if (key.equals(MutableProcessingConfiguration.C_FORMAT_KEY)) {
            valueSafeyChecker = (env, actualValue) -> {
                if (actualValue.startsWith("@")
                        || StandardCFormats.STANDARD_C_FORMATS.containsKey(actualValue)
                        || actualValue.equals("default")) {
                    return;
                }
                throw new TemplateException("It's not allowed to set \"" + key + "\" to "
                        + _StringUtils.jQuote(actualValue) + " in a template. Use a standard c format name ("
                        + _StringUtils.toCommaSeparatedJQuotedItems(StandardCFormats.STANDARD_C_FORMATS.keySet())
                        + "), or registered custom  c format name after a \"@\".",
                        env);
            };
        } else {
            valueSafeyChecker = null;
        }
    }

    @Override
    ASTElement[] execute(Environment env) throws TemplateException {
        TemplateModel mval = value.eval(env);
        String strval;
        if (mval instanceof TemplateStringModel) {
            strval = ((TemplateStringModel) mval).getAsString();
        } else if (mval instanceof TemplateBooleanModel) {
            strval = ((TemplateBooleanModel) mval).getAsBoolean() ? "true" : "false";
        } else if (mval instanceof TemplateNumberModel) {
            strval = ((TemplateNumberModel) mval).getAsNumber().toString();
        } else {
            strval = value.evalAndCoerceToStringOrUnsupportedMarkup(env);
        }
        if (valueSafeyChecker != null) {
            valueSafeyChecker.check(env, strval);
        }
        try {
            env.setSetting(key, strval);
        } catch (ConfigurationException e) {
            throw new TemplateException(env, e.getMessage(), e.getCause());
        }
        return null;
    }
    
    @Override
    String dump(boolean canonical) {
        StringBuilder sb = new StringBuilder();
        if (canonical) sb.append('<');
        sb.append(getLabelWithoutParameters());
        sb.append(' ');
        sb.append(_StringUtils.toFTLTopLevelTragetIdentifier(key));
        sb.append('=');
        sb.append(value.getCanonicalForm());
        if (canonical) sb.append("/>");
        return sb.toString();
    }
    
    @Override
    public String getLabelWithoutParameters() {
        return "#setting";
    }

    @Override
    int getParameterCount() {
        return 2;
    }

    @Override
    Object getParameterValue(int idx) {
        switch (idx) {
        case 0: return key;
        case 1: return value;
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    ParameterRole getParameterRole(int idx) {
        switch (idx) {
        case 0: return ParameterRole.ITEM_KEY;
        case 1: return ParameterRole.ITEM_VALUE;
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    boolean isNestedBlockRepeater() {
        return false;
    }

    @FunctionalInterface
    private interface ValueSafetyChecker {
        void check(Environment env, String value) throws TemplateException;
    }

}
