/*
 * 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 freemarker.core;

import java.util.Arrays;

import freemarker.template.Configuration;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;
import freemarker.template._TemplateAPI;
import freemarker.template.utility.StringUtil;

/**
 * An instruction that sets a property of the template rendering
 * environment.
 */
final class PropertySetting extends TemplateElement {

    private final String key;
    private final Expression value;
    
    static final String[] SETTING_NAMES = new String[] {
            // Must be sorted alphabetically!
            Configurable.BOOLEAN_FORMAT_KEY_CAMEL_CASE,
            Configurable.BOOLEAN_FORMAT_KEY_SNAKE_CASE,
            Configurable.CLASSIC_COMPATIBLE_KEY_CAMEL_CASE,
            Configurable.CLASSIC_COMPATIBLE_KEY_SNAKE_CASE,
            Configurable.DATE_FORMAT_KEY_CAMEL_CASE,
            Configurable.DATE_FORMAT_KEY_SNAKE_CASE,
            Configurable.DATETIME_FORMAT_KEY_CAMEL_CASE,
            Configurable.DATETIME_FORMAT_KEY_SNAKE_CASE,
            Configurable.LOCALE_KEY,
            Configurable.NUMBER_FORMAT_KEY_CAMEL_CASE,
            Configurable.NUMBER_FORMAT_KEY_SNAKE_CASE,
            Configurable.OUTPUT_ENCODING_KEY_CAMEL_CASE,
            Configurable.OUTPUT_ENCODING_KEY_SNAKE_CASE,
            Configurable.SQL_DATE_AND_TIME_TIME_ZONE_KEY_CAMEL_CASE,
            Configurable.SQL_DATE_AND_TIME_TIME_ZONE_KEY,
            Configurable.TIME_FORMAT_KEY_CAMEL_CASE,
            Configurable.TIME_ZONE_KEY_CAMEL_CASE,
            Configurable.TIME_FORMAT_KEY_SNAKE_CASE,
            Configurable.TIME_ZONE_KEY_SNAKE_CASE,
            Configurable.URL_ESCAPING_CHARSET_KEY_CAMEL_CASE,
            Configurable.URL_ESCAPING_CHARSET_KEY_SNAKE_CASE
    };

    PropertySetting(Token keyTk, FMParserTokenManager tokenManager, Expression value, Configuration cfg)
            throws ParseException {
        String key = keyTk.image;
        if (Arrays.binarySearch(SETTING_NAMES, key) < 0) {
            StringBuilder sb = new StringBuilder();
            if (_TemplateAPI.getConfigurationSettingNames(cfg, true).contains(key)
                    || _TemplateAPI.getConfigurationSettingNames(cfg, false).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(StringUtil.jQuote(key)).append(".");
                sb.append(" The allowed setting names are: ");

                int shownNamingConvention;
                {
                    int namingConvention = tokenManager.namingConvention;
                    shownNamingConvention = namingConvention != Configuration.AUTO_DETECT_NAMING_CONVENTION
                            ? namingConvention : Configuration.LEGACY_NAMING_CONVENTION /* [2.4] CAMEL_CASE */; 
                }
                
                boolean first = true;
                for (int i = 0; i < SETTING_NAMES.length; i++) {
                    String correctName = SETTING_NAMES[i];
                    int correctNameNamingConvetion = _CoreStringUtils.getIdentifierNamingConvention(correctName);
                    if (shownNamingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION 
                            ? correctNameNamingConvetion != Configuration.LEGACY_NAMING_CONVENTION
                            : correctNameNamingConvetion != Configuration.CAMEL_CASE_NAMING_CONVENTION) {
                        if (first) {
                            first = false;
                        } else {
                            sb.append(", ");
                        }
                    
                        sb.append(SETTING_NAMES[i]);
                    }
                }
            }
            throw new ParseException(sb.toString(), null, keyTk);
        }
        
        this.key = key;
        this.value = value;
    }

    @Override
    TemplateElement[] accept(Environment env) throws TemplateException {
        TemplateModel mval = value.eval(env);
        String strval;
        if (mval instanceof TemplateScalarModel) {
            strval = ((TemplateScalarModel) 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);
        }
        env.setSetting(key, strval);
        return null;
    }
    
    @Override
    protected String dump(boolean canonical) {
        StringBuilder sb = new StringBuilder();
        if (canonical) sb.append('<');
        sb.append(getNodeTypeSymbol());
        sb.append(' ');
        sb.append(_CoreStringUtils.toFTLTopLevelTragetIdentifier(key));
        sb.append('=');
        sb.append(value.getCanonicalForm());
        if (canonical) sb.append("/>");
        return sb.toString();
    }
    
    @Override
    String getNodeTypeSymbol() {
        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;
    }
    
}
