/*
 *
 *  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.royale.linter.config;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.royale.compiler.common.IPathResolver;
import org.apache.royale.compiler.exceptions.ConfigurationException;
import org.apache.royale.compiler.exceptions.ConfigurationException.CannotOpen;
import org.apache.royale.compiler.internal.config.annotations.Arguments;
import org.apache.royale.compiler.internal.config.annotations.Config;
import org.apache.royale.compiler.internal.config.annotations.InfiniteArguments;
import org.apache.royale.compiler.internal.config.annotations.Mapping;
import org.apache.royale.compiler.problems.DeprecatedConfigurationOptionProblem;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.RemovedConfigurationOptionProblem;
import org.apache.royale.utils.FilenameNormalization;

import com.google.common.collect.ImmutableList;

public class Configuration {

    private static Map<String, String> aliases = null;

    public static Map<String, String> getAliases() {
        if (aliases == null) {
            aliases = new HashMap<String, String>();

            // aliases.put("s", "short-option");
        }
        return aliases;
    }

    //
    // PathResolver
    //
    private IPathResolver pathResolver;

    /**
     * Set a path resolver to resolver files relative to a configuration. Files inside of configuration files are
     * resolved relative to those configuration files and files on the command line are resolved relative to the root
     * directory of the compile.
     * 
     * @param pathResolver a path resolver for this configuration. May not be null.
     */
    public void setPathResolver(IPathResolver pathResolver)
    {
        this.pathResolver = pathResolver;
    }

    /**
     * Collection of fatal and non-fatal configuration problems.
     */
    private Collection<ICompilerProblem> configurationProblems = new ArrayList<ICompilerProblem>();

    /**
     * Get the configuration problems. This should be called after the configuration
     * has been processed.
     * 
     * @return a collection of fatal and non-fatal configuration problems.
     */
    public Collection<ICompilerProblem> getConfigurationProblems() {
        return configurationProblems;
    }

    /**
     * Validate configuration options values.
     * 
     * @param configurationBuffer Configuration buffer.
     * @throws ConfigurationException Error.
     */
    public void validate(ConfigurationBuffer configurationBuffer) throws ConfigurationException {
        // process the merged configuration buffer. right, can't just process the args.
        processDeprecatedAndRemovedOptions(configurationBuffer);
    }

    private void processDeprecatedAndRemovedOptions(ConfigurationBuffer configurationBuffer) {
        for (final String var : configurationBuffer.getVars()) {
            ConfigurationInfo info = configurationBuffer.getInfo(var);
            List<ConfigurationValue> values = configurationBuffer.getVar(var);
            if (values != null) {
                for (final ConfigurationValue cv : values) {
                    if (info.isRemoved()) {
                        addRemovedConfigurationOptionProblem(cv);
                    } else if (info.isDeprecated() && configurationBuffer.getVar(var) != null) {
                        String replacement = info.getDeprecatedReplacement();
                        String since = info.getDeprecatedSince();
                        DeprecatedConfigurationOptionProblem problem = new DeprecatedConfigurationOptionProblem(var,
                                replacement, since, cv.getSource(), cv.getLine());
                        configurationProblems.add(problem);
                    }
                }
            }
        }
    }

    /**
     * Add a RemovedConfigurationOptionProblem to the list of configuration
     * problems.
     * 
     * @param cv
     */
    private void addRemovedConfigurationOptionProblem(ConfigurationValue cv) {
        RemovedConfigurationOptionProblem problem = new RemovedConfigurationOptionProblem(cv.getVar(), cv.getSource(),
                cv.getLine());
        configurationProblems.add(problem);
    }

    //
    // 'help' option from CommandLineConfiguration
    //

    /**
     * dummy, just a trigger for help text
     */
    @Config(displayed = false, greedy = true)
    @Arguments("keyword")
    @InfiniteArguments
    public void setHelp(ConfigurationValue cv, String[] keywords) {

    }

    //
    // 'version' option from CommandLineConfiguration
    //

    /**
     * Dummy option. Just a trigger for version info.
     */
    @Config
    public void setVersion(ConfigurationValue cv, boolean value) {
    }

    //
    // 'load-config' option from CommandLineConfiguration
    //

    private String configFile = null;

    /**
     * @return Normalized path to a Flex configuration file.
     */
    public String getLoadConfig()
    {
        return configFile;
    }

    /**
     * Since {@link ConfigurationBuffer} loads the "load-config" files, the value of this configuration option isn't
     * intersting to the rest part of the compiler.
     */
    @Config(allowMultiple = true)
    @Arguments("filename")
    public void setLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException
    {
        configFile = resolvePathStrict(filename, cv);   
    }

    //
    // 'files' option
    //

    private List<String> files = new ArrayList<String>();

    /**
     * @return A list of filespecs. It's the default variable for command line.
     */
    public List<String> getFiles() {
        return files;
    }

    @Config(allowMultiple = true, hidden = true)
    @Mapping("files")
    @Arguments(Arguments.PATH_ELEMENT)
    @InfiniteArguments
    public void setFiles(ConfigurationValue cv, List<String> args) throws ConfigurationException {
        this.files.addAll(args);
    }

    //
    // 'recommended' option
    //

    private boolean recommended = false;

    public boolean getRecommended() {
        return recommended;
    }

    @Config
    @Mapping("recommended")
    public void setRecommended(ConfigurationValue cv, boolean b) {
        this.recommended = b;
        duplicateObjectKeys = recommended;
        emptyStatement = recommended;
        ifBoolean = recommended;
        leadingZero = recommended;
        sparseArray = recommended;
        unsafeNegation = recommended;
        validTypeof = recommended;
        with = recommended;
    }

    //
    // 'ignore-parsing-problems' option
    //

    private boolean ignoreParsingProblems = false;

    public boolean getIgnoreParsingProblems() {
        return ignoreParsingProblems;
    }

    @Config(advanced = true)
    @Mapping("ignore-parsing-problems")
    public void setIgnoreParsingProblems(ConfigurationValue cv, boolean b) {
        this.ignoreParsingProblems = b;
    }

    //
    // 'any-type' option
    //

    private boolean anyType = false;

    public boolean getAnyType() {
        return anyType;
    }

    @Config
    @Mapping("any-type")
    public void setAnyType(ConfigurationValue cv, boolean b) {
        this.anyType = b;
    }

    //
    // 'boolean-equality' option
    //

    private boolean booleanEquality = false;

    public boolean getBooleanEquality() {
        return booleanEquality;
    }

    @Config
    @Mapping("boolean-equality")
    public void setBooleanEquality(ConfigurationValue cv, boolean b) {
        this.booleanEquality = b;
    }

    //
    // 'class-name' option
    //

    private boolean className = false;

    public boolean getClassName() {
        return className;
    }

    @Config
    @Mapping("class-name")
    public void setClassName(ConfigurationValue cv, boolean b) {
        this.className = b;
    }

    //
    // 'constant-name' option
    //

    private boolean constantName = false;

    public boolean getConstantName() {
        return constantName;
    }

    @Config
    @Mapping("constant-name")
    public void setConstantName(ConfigurationValue cv, boolean b) {
        this.constantName = b;
    }

    //
    // 'duplicate-object-keys' option
    //

    private boolean duplicateObjectKeys = false;

    public boolean getDuplicateObjectKeys() {
        return duplicateObjectKeys;
    }

    @Config
    @Mapping("duplicate-object-keys")
    public void setDuplicateObjectKeys(ConfigurationValue cv, boolean b) {
        this.duplicateObjectKeys = b;
    }

    //
    // 'constructor-dispatch-event' option
    //

    private boolean constructorDispatchEvent = false;

    public boolean getConstructorDispatchEvent() {
        return constructorDispatchEvent;
    }

    @Config
    @Mapping("constructor-dispatch-event")
    public void setConstructorDispatchEvent(ConfigurationValue cv, boolean b) {
        this.constructorDispatchEvent = b;
    }

    //
    // 'constructor-return-type' option
    //

    private boolean constructorReturnType = false;

    public boolean getConstructorReturnType() {
        return constructorReturnType;
    }

    @Config
    @Mapping("constructor-return-type")
    public void setConstructorReturnType(ConfigurationValue cv, boolean b) {
        this.constructorReturnType = b;
    }

    //
    // 'dynamic-class' option
    //

    private boolean dynamicClass = false;

    public boolean getDynamicClass() {
        return dynamicClass;
    }

    @Config
    @Mapping("dynamic-class")
    public void setDynamicClass(ConfigurationValue cv, boolean b) {
        this.dynamicClass = b;
    }

    //
    // 'empty-comment' option
    //

    private boolean emptyComment = false;

    public boolean getEmptyComment() {
        return emptyComment;
    }

    @Config
    @Mapping("empty-comment")
    public void setEmptyComment(ConfigurationValue cv, boolean b) {
        this.emptyComment = b;
    }

    //
    // 'empty-function-body' option
    //

    private boolean emptyFunctionBody = false;

    public boolean getEmptyFunctionBody() {
        return emptyFunctionBody;
    }

    @Config
    @Mapping("empty-function-body")
    public void setEmptyFunctionBody(ConfigurationValue cv, boolean b) {
        this.emptyFunctionBody = b;
    }

    //
    // 'empty-nested-block' option
    //

    private boolean emptyNestedBlock = false;

    public boolean getEmptyNestedBlock() {
        return emptyNestedBlock;
    }

    @Config
    @Mapping("empty-nested-block")
    public void setEmptyNestedBlock(ConfigurationValue cv, boolean b) {
        this.emptyNestedBlock = b;
    }

    //
    // 'empty-statement' option
    //

    private boolean emptyStatement = false;

    public boolean getEmptyStatement() {
        return emptyStatement;
    }

    @Config
    @Mapping("empty-statement")
    public void setEmptyStatement(ConfigurationValue cv, boolean b) {
        this.emptyStatement = b;
    }

    //
    // 'field-name' option
    //

    private boolean fieldName = false;

    public boolean getFieldName() {
        return fieldName;
    }

    @Config
    @Mapping("field-name")
    public void setFieldName(ConfigurationValue cv, boolean b) {
        this.fieldName = b;
    }

    //
    // 'function-name' option
    //

    private boolean functionName = false;

    public boolean getFunctionName() {
        return functionName;
    }

    @Config
    @Mapping("function-name")
    public void setFunctionName(ConfigurationValue cv, boolean b) {
        this.functionName = b;
    }

    //
    // 'if-boolean' option
    //

    private boolean ifBoolean = false;

    public boolean getIfBoolean() {
        return ifBoolean;
    }

    @Config
    @Mapping("if-boolean")
    public void setIfBoolean(ConfigurationValue cv, boolean b) {
        this.ifBoolean = b;
    }

    //
    // 'interface-name' option
    //

    private boolean interfaceName = false;

    public boolean getInterfaceName() {
        return interfaceName;
    }

    @Config
    @Mapping("interface-name")
    public void setInterfaceName(ConfigurationValue cv, boolean b) {
        this.interfaceName = b;
    }

    //
    // 'line-comment-position' option
    //

    private LineCommentPosition lineCommentPosition = null;

    public String getLineCommentPosition() {
        if (lineCommentPosition == null) {
            return null;
        }
        return lineCommentPosition.getPosition();
    }

    @Config
    @Mapping("line-comment-position")
    public void setLineCommentPosition(ConfigurationValue cv, String s) {
        this.lineCommentPosition = LineCommentPosition.valueOf(s.toUpperCase());
    }

    //
    // 'local-var-param-name' option
    //

    private boolean localVarParamName = false;

    public boolean getLocalVarParamName() {
        return localVarParamName;
    }

    @Config
    @Mapping("local-var-param-name")
    public void setLocalVarParamName(ConfigurationValue cv, boolean b) {
        this.localVarParamName = b;
    }

    //
    // 'local-var-shadows-field' option
    //

    private boolean localVarShadowsField = false;

    public boolean getLocalVarShadowsField() {
        return localVarShadowsField;
    }

    @Config
    @Mapping("local-var-shadows-field")
    public void setLocalVarShadowsField(ConfigurationValue cv, boolean b) {
        this.localVarShadowsField = b;
    }

    //
    // 'max-block-depth' option
    //

    private int maxBlockDepth = 0;

    public int getMaxBlockDepth() {
        return maxBlockDepth;
    }

    @Config
    @Mapping("max-block-depth")
    public void setMaxBlockDepth(ConfigurationValue cv, int i) {
        this.maxBlockDepth = i;
    }

    //
    // 'max-params' option
    //

    private int maxParams = 0;

    public int getMaxParams() {
        return maxParams;
    }

    @Config
    @Mapping("max-params")
    public void setMaxParams(ConfigurationValue cv, int i) {
        this.maxParams = i;
    }

    //
    // 'missing-asdoc' option
    //

    private boolean missingAsdoc = false;

    public boolean getMissingAsdoc() {
        return missingAsdoc;
    }

    @Config
    @Mapping("missing-asdoc")
    public void setMissingAsdoc(ConfigurationValue cv, boolean b) {
        this.missingAsdoc = b;
    }

    //
    // 'missing-constructor-super' option
    //

    private boolean missingConstructorSuper = false;

    public boolean getMissingConstructorSuper() {
        return missingConstructorSuper;
    }

    @Config
    @Mapping("missing-constructor-super")
    public void setMissingConstructorSuper(ConfigurationValue cv, boolean b) {
        this.missingConstructorSuper = b;
    }

    //
    // 'missing-namespace' option
    //

    private boolean missingNamespace = false;

    public boolean getMissingNamespace() {
        return missingNamespace;
    }

    @Config
    @Mapping("missing-namespace")
    public void setMissingNamespace(ConfigurationValue cv, boolean b) {
        this.missingNamespace = b;
    }

    //
    // 'missing-semicolon' option
    //

    private boolean missingSemicolon = false;

    public boolean getMissingSemicolon() {
        return missingSemicolon;
    }

    @Config
    @Mapping("missing-semicolon")
    public void setMissingSemicolon(ConfigurationValue cv, boolean b) {
        this.missingSemicolon = b;
    }

    //
    // 'missing-type' option
    //

    private boolean missingType = false;

    public boolean getMissingType() {
        return missingType;
    }

    @Config
    @Mapping("missing-type")
    public void setMissingType(ConfigurationValue cv, boolean b) {
        this.missingType = b;
    }

    //
    // 'mxml-empty-attr' option
    //

    private boolean mxmlEmptyAttr = false;

    public boolean getMxmlEmptyAttr() {
        return mxmlEmptyAttr;
    }

    @Config
    @Mapping("mxml-empty-attr")
    public void setMxmlEmptyAttr(ConfigurationValue cv, boolean b) {
        this.mxmlEmptyAttr = b;
    }

    //
    // 'mxml-id' option
    //

    private boolean mxmlId = false;

    public boolean getMxmlId() {
        return mxmlId;
    }

    @Config
    @Mapping("mxml-id")
    public void setMxmlId(ConfigurationValue cv, boolean b) {
        this.mxmlId = b;
    }

    //
    // 'leading-zero' option
    //

    private boolean leadingZero = false;

    public boolean getLeadingZero() {
        return leadingZero;
    }

    @Config
    @Mapping("leading-zero")
    public void setLeadingZero(ConfigurationValue cv, boolean b) {
        this.leadingZero = b;
    }

    //
    // 'override-super' option
    //

    private boolean overrideSuper = false;

    public boolean getOverrideSuper() {
        return overrideSuper;
    }

    @Config
    @Mapping("override-super")
    public void setOverrideSuper(ConfigurationValue cv, boolean b) {
        this.overrideSuper = b;
    }

    //
    // 'package-name' option
    //

    private boolean packageName = false;

    public boolean getPackageName() {
        return packageName;
    }

    @Config
    @Mapping("package-name")
    public void setPackageName(ConfigurationValue cv, boolean b) {
        this.packageName = b;
    }

    //
    // 'sparse-array' option
    //

    private boolean sparseArray = false;

    public boolean getSparseArray() {
        return sparseArray;
    }

    @Config
    @Mapping("sparse-array")
    public void setSparseArray(ConfigurationValue cv, boolean b) {
        this.sparseArray = b;
    }

    //
    // 'static-constants' option
    //

    private boolean staticConstants = false;

    public boolean getStaticConstants() {
        return staticConstants;
    }

    @Config
    @Mapping("static-constants")
    public void setStaticConstants(ConfigurationValue cv, boolean b) {
        this.staticConstants = b;
    }

    //
    // 'strict-equality' option
    //

    private boolean strictEquality = false;

    public boolean getStrictEquality() {
        return strictEquality;
    }

    @Config
    @Mapping("strict-equality")
    public void setStrictEquality(ConfigurationValue cv, boolean b) {
        this.strictEquality = b;
    }

    //
    // 'string-event' option
    //

    private boolean stringEvent = false;

    public boolean getStringEvent() {
        return stringEvent;
    }

    @Config
    @Mapping("string-event")
    public void setStringEvent(ConfigurationValue cv, boolean b) {
        this.stringEvent = b;
    }

    //
    // 'switch-default' option
    //

    private boolean switchDefault = false;

    public boolean getSwitchDefault() {
        return switchDefault;
    }

    @Config
    @Mapping("switch-default")
    public void setSwitchDefault(ConfigurationValue cv, boolean b) {
        this.switchDefault = b;
    }

    //
    // 'this-closure' option
    //

    private boolean thisClosure = false;

    public boolean getThisClosure() {
        return thisClosure;
    }

    @Config
    @Mapping("this-closure")
    public void setThisClosure(ConfigurationValue cv, boolean b) {
        this.thisClosure = b;
    }

    //
    // 'trace' option
    //

    private boolean trace = false;

    public boolean getTrace() {
        return trace;
    }

    @Config
    @Mapping("trace")
    public void setTrace(ConfigurationValue cv, boolean b) {
        this.trace = b;
    }

    //
    // 'unsafe-negation' option
    //

    private boolean unsafeNegation = false;

    public boolean getUnsafeNegation() {
        return unsafeNegation;
    }

    @Config
    @Mapping("unsafe-negation")
    public void setUnsafeNegation(ConfigurationValue cv, boolean b) {
        this.unsafeNegation = b;
    }

    //
    // 'valid-typeof' option
    //

    private boolean validTypeof = false;

    public boolean getValidTypeof() {
        return validTypeof;
    }

    @Config
    @Mapping("valid-typeof")
    public void setValidTypeof(ConfigurationValue cv, boolean b) {
        this.validTypeof = b;
    }

    //
    // 'vars-on-top' option
    //

    private boolean varsOnTop = false;

    public boolean getVarsOnTop() {
        return varsOnTop;
    }

    @Config
    @Mapping("vars-on-top")
    public void setVarsOnTop(ConfigurationValue cv, boolean b) {
        this.varsOnTop = b;
    }

    //
    // 'void-operator' option
    //

    private boolean voidOperator = false;

    public boolean getVoidOperator() {
        return voidOperator;
    }

    @Config
    @Mapping("void-operator")
    public void setVoidOperator(ConfigurationValue cv, boolean b) {
        this.voidOperator = b;
    }

    //
    // 'wildcard-import' option
    //

    private boolean wildcardImport = false;

    public boolean getWildcardImport() {
        return wildcardImport;
    }

    @Config
    @Mapping("wildcard-import")
    public void setWildcardImport(ConfigurationValue cv, boolean b) {
        this.wildcardImport = b;
    }

    //
    // 'with' option
    //

    private boolean with = false;

    public boolean getWith() {
        return with;
    }

    @Config
    @Mapping("with")
    public void setWith(ConfigurationValue cv, boolean b) {
        this.with = b;
    }

    /**
     * 
     * @param path A path to resolve.
     * @param cv Configuration context.
     * @return A single normalized resolved file. If the path could be expanded into more than one path, then use
     *         {@link resolvePathsStrict}
     * @throws CannotOpen
     */
    protected String resolvePathStrict(final String path, final ConfigurationValue cv) throws CannotOpen
    {
        return resolvePathStrict(path, cv, false);
    }

    /**
     * Resolve a single path. This is a more strict version of {@link #resolvePaths()} in that it throws
     * {@link CannotOpen} exception when a file path element can't be resolved.
     * 
     * @param path A path to resolve.
     * @param cv Configuration context.
     * @param returnMissingFiles Determines if the CannotOpen exception is thrown if a file does not exist. Pass true to
     *        disable exceptions and return files that do not exist. Pass false to throw exceptions.
     * @return A single normalized resolved file. If the path could be expanded into more than one path, then use
     *         {@link resolvePathsStrict}.
     * @throws CannotOpen error
     * @see #resolvePaths(ImmutableList, ConfigurationValue)
     */
    private String resolvePathStrict(final String path, final ConfigurationValue cv, final boolean returnMissingFiles)
            throws CannotOpen
    {
        ImmutableList<String> singletonPath = ImmutableList.of(path);
        ImmutableList<String> results = resolvePathsStrict(singletonPath, cv, returnMissingFiles);
        return results.get(0);
    }

    /**
     * Resolve a list of paths. This is a more strict version of {@link #resolvePaths()} in that it throws
     * {@link CannotOpen} exception when a file path element can't be resolved.
     * 
     * @param paths A list of paths to resolve.
     * @param cv Configuration context.
     * @return A list of normalized resolved file paths.
     * @throws CannotOpen error
     * @see #resolvePaths(ImmutableList, ConfigurationValue)
     */
    private ImmutableList<String> resolvePathsStrict(final ImmutableList<String> paths, final ConfigurationValue cv)
            throws CannotOpen
    {
        return resolvePathsStrict(paths, cv, false);
    }

    /**
     * Resolve a list of paths. This is a more strict version of {@link #resolvePaths()} in that it throws
     * {@link CannotOpen} exception when a file path element can't be resolved.
     * 
     * @param paths A list of paths to resolve.
     * @param cv Configuration context.
     * @param returnMissingFiles Determines if the CannotOpen exception is thrown if a file does not exist. Pass true to
     *        disable exceptions and return files that do not exist. Pass false to throw exceptions.
     * @return A list of normalized resolved file paths.
     * @throws CannotOpen error
     * @see #resolvePaths(ImmutableList, ConfigurationValue)
     */
    private ImmutableList<String> resolvePathsStrict(final ImmutableList<String> paths, final ConfigurationValue cv,
            final boolean returnMissingFiles) throws CannotOpen
    {
        assert paths != null : "Expected paths";
        assert cv != null : "Require ConfigurationValue as context.";

        final ImmutableList.Builder<String> resolvedPathsBuilder = new ImmutableList.Builder<String>();
        for (String processedPath : paths)
        {
            if (cv.getContext() != null)
            {
                boolean isAbsolute = new File(processedPath).isAbsolute();
                if (!isAbsolute)
                    processedPath = new File(cv.getContext(), processedPath).getAbsolutePath();
            }
            if (processedPath.contains("*"))
            {
                // if contains wild card, just prove the part before the wild card is valid
                int c = processedPath.lastIndexOf(File.separator, processedPath.indexOf("*"));
                if (c != -1)
                    processedPath = processedPath.substring(0, c);
            }
            if (!processedPath.contains(".swc:"))
            {
	            final File fileSpec = pathResolver.resolve(processedPath);
	            if (!returnMissingFiles && !fileSpec.exists())
	            {
	                throw new CannotOpen(FilenameNormalization.normalize(processedPath), cv.getVar(), cv.getSource(),
	                        cv.getLine());
	            }
	            resolvedPathsBuilder.add(fileSpec.getAbsolutePath());
            }
            else
                resolvedPathsBuilder.add(processedPath);
        }
        return resolvedPathsBuilder.build();
    }
}
