/*
 *
 *  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.flex.compiler.internal.driver.js.goog;

import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.flex.compiler.clients.JSConfiguration;
import org.apache.flex.compiler.clients.MXMLJSC;
import org.apache.flex.compiler.config.ConfigurationValue;
import org.apache.flex.compiler.exceptions.ConfigurationException;
import org.apache.flex.compiler.internal.config.annotations.Arguments;
import org.apache.flex.compiler.internal.config.annotations.Config;
import org.apache.flex.compiler.internal.config.annotations.FlexOnly;
import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
import org.apache.flex.compiler.internal.config.annotations.Mapping;

/**
 * The {@link JSGoogConfiguration} class holds all compiler arguments needed for
 * compiling ActionScript to JavaScript the 'goog' way.
 * <p>
 * Specific flags are implemented here for the configuration to be loaded by the
 * configure() method of {@link MXMLJSC}.
 * <p>
 * This class inherits all compiler arguments from the MXMLC compiler.
 * 
 * @author Erik de Bruin
 */
public class JSGoogConfiguration extends JSConfiguration
{
    public JSGoogConfiguration()
    {
    }

    //
    // 'closure-lib'
    //

    protected String closureLib = "";

    public boolean isClosureLibSet() {
        return !closureLib.isEmpty();
    }

    public String getClosureLib()
    {
        try
        {
            if (closureLib.equals(""))
            {
                return getAbsolutePathFromPathRelativeToMXMLC(
                        "../../js/lib/google/closure-library");
            }
        }
        catch (Exception e) { /* better to try and fail... */ }
        
        return closureLib;
    }

    @Config
    @Mapping("closure-lib")
    public void setClosureLib(ConfigurationValue cv, String value)
            throws ConfigurationException
    {
        if (value != null)
            closureLib = value;
    }

    //
    // Override 'compiler.binding-value-change-event-type'
    //

    private String bindingValueChangeEventType = "valueChange";

    @Override
    public String getBindingValueChangeEventType()
    {
        return bindingValueChangeEventType;
    }

    @Override
    @Config(advanced = true)
    public void setCompilerBindingValueChangeEventType(ConfigurationValue cv, String b)
    {
        bindingValueChangeEventType = b;
    }

    //
    // Override 'compiler.mxml.children-as-data'
    //
    
    private Boolean childrenAsData = true;
    
    @Override
    public Boolean getCompilerMxmlChildrenAsData()
    {
        return childrenAsData;
    }

    @Override
    @Config
    @Mapping({"compiler", "mxml", "children-as-data"})
    @FlexOnly
    public void setCompilerMxmlChildrenAsData(ConfigurationValue cv, Boolean asData) throws ConfigurationException
    {
        childrenAsData = asData;
    }

    //
    // 'marmotinni'
    //

    private String marmotinni;

    public String getMarmotinni()
    {
        return marmotinni;
    }

    @Config
    @Mapping("marmotinni")
    public void setMarmotinni(ConfigurationValue cv, String value)
            throws ConfigurationException
    {
        marmotinni = value;
    }

    //
    // 'sdk-js-lib'
    //

    protected List<String> sdkJSLib = new ArrayList<String>();

    public List<String> getSDKJSLib()
    {
        if (sdkJSLib.size() == 0)
        {
            try
            {
                String path = getAbsolutePathFromPathRelativeToMXMLC(
                            "../../frameworks/js/FlexJS/src");

                sdkJSLib.add(path);
            }
            catch (Exception e) { /* better to try and fail... */ }
        }
        
        return sdkJSLib;
    }

    @Config(allowMultiple = true)
    @Mapping("sdk-js-lib")
    @InfiniteArguments
    public void setSDKJSLib(ConfigurationValue cv, List<String> value)
            throws ConfigurationException
    {
        sdkJSLib.addAll(value);
    }

    //
    // 'external-js-lib'
    //

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

    public List<String> getExternalJSLib()
    {
        return externalJSLib;
    }

    @Config(allowMultiple = true)
    @Mapping("external-js-lib")
    @InfiniteArguments
    public void setExternalJSLib(ConfigurationValue cv, List<String> value)
            throws ConfigurationException
    {
        externalJSLib.addAll(value);
    }

    //
    // 'strict-publish'
    //

    private boolean strictPublish = true;

    public boolean getStrictPublish()
    {
        return strictPublish;
    }

    @Config
    @Mapping("strict-publish")
    public void setStrictPublish(ConfigurationValue cv, boolean value)
            throws ConfigurationException
    {
        strictPublish = value;
    }

    //
    // 'keep-asdoc'
    //

    private boolean keepASDoc = true;

    public boolean getKeepASDoc()
    {
        return keepASDoc;
    }

    @Config
    @Mapping("keep-asdoc")
    public void setKeepASDoc(ConfigurationValue cv, boolean value)
            throws ConfigurationException
    {
    	keepASDoc = value;
    }

    
    
    //
    // 'remove-circulars'
    //

    private boolean removeCirculars = false;

    public boolean getRemoveCirculars()
    {
        return removeCirculars;
    }

    @Config
    @Mapping("remove-circulars")
    public void setRemoveCirculars(ConfigurationValue cv, boolean value)
            throws ConfigurationException
    {
    	removeCirculars = value;
    }

    
    //
    // 'skip-transpile'
    //

    private boolean skipTranspile = false;

    public boolean getSkipTranspile()
    {
        return skipTranspile;
    }

    @Config
    @Mapping("skip-transpile")
    public void setSkipTranspile(ConfigurationValue cv, boolean value)
            throws ConfigurationException
    {
    	skipTranspile = value;
    }
    
    
    
    protected String getAbsolutePathFromPathRelativeToMXMLC(String relativePath)
        throws IOException
    {
        String mxmlcURL = MXMLJSC.class.getProtectionDomain().getCodeSource()
                .getLocation().getPath();

        File mxmlc = new File(URLDecoder.decode(mxmlcURL, "utf-8"));
        
        return new File(mxmlc.getParent() + File.separator + relativePath)
                .getCanonicalPath();
    }

    //
    // 'js-compiler-option'
    //

    protected List<String> jsCompilerOptions = new ArrayList<String>();

    public List<String> getJSCompilerOptions()
    {
        return jsCompilerOptions;
    }

    @Config(allowMultiple = true)
    @Mapping("js-compiler-option")
    @InfiniteArguments
    public void setJSCompilerOptions(ConfigurationValue cv, List<String> value)
            throws ConfigurationException
    {
    	jsCompilerOptions.addAll(value);
    }

    //
    // 'js-output-optimization'
    //

    protected List<String> jsOutputOptimizations = new ArrayList<String>();

    public List<String> getJSOutputOptimizations()
    {
        return jsOutputOptimizations;
    }

    @Config(allowMultiple = true)
    @Mapping("js-output-optimization")
    @InfiniteArguments
    public void setJSOutputOptimizations(ConfigurationValue cv, List<String> value)
            throws ConfigurationException
    {
    	jsOutputOptimizations.addAll(value);
    }

    // 'html-template' option
    //

    private String htmlTemplateFileName = null;

    public File getHtmlTemplate()
    {
        return htmlTemplateFileName != null ? new File(htmlTemplateFileName) : null;
    }

    /**
     * Specify an HTML template with tokens to replace with application-specific values.
     * If not specified a standard template is generated.
     */
    @Config(advanced = true)
    @Mapping("html-template")
    @Arguments("filename")
    public void setHtmlTemplate(ConfigurationValue cv, String filename)
    {
        this.htmlTemplateFileName = getOutputPath(cv, filename);
    }

    // 'html-output-filename' option
    //

    private String htmlOutputFileName = "index.html";

    public String getHtmlOutputFileName()
    {
        return htmlOutputFileName;
    }

    /**
     * Specify the name of the HTML file that goes in the output folder.  Default is index.html.
     */
    @Config(advanced = true)
    @Mapping("html-output-filename")
    @Arguments("filename")
    public void setHtmlOutputFileName(ConfigurationValue cv, String filename)
    {
        this.htmlOutputFileName = filename;
    }

    //
    // 'compiler.keep-code-with-metadata' option
    //

    private Set<String> keepCodeWithMetadata = null;

    public Set<String> getCompilerKeepCodeWithMetadata()
    {
        return keepCodeWithMetadata == null ? Collections.<String> emptySet() : keepCodeWithMetadata;
    }

    @Config(advanced = true, allowMultiple = true)
    @Mapping({ "compiler", "keep-code-with-metadata" })
    @Arguments("name")
    @InfiniteArguments
    public void setCompilerKeepCodeWithMetadata(ConfigurationValue cv, List<String> values)
    {
        if (keepCodeWithMetadata == null)
        	keepCodeWithMetadata = new HashSet<String>();
        keepCodeWithMetadata.addAll(values);
    }


}
