/*
 *  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.harmony.pack200;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.objectweb.asm.Attribute;

/**
 * Utility class to manage the various options available for pack200
 */
public class PackingOptions {

    public static final String STRIP = "strip";
    public static final String ERROR = "error";
    public static final String PASS = "pass";
    public static final String KEEP = "keep";

    // All options are initially set to their defaults
    private boolean repack = false;
    private boolean gzip = true;
    private boolean stripDebug = false;
    private boolean keepFileOrder = true;
    private long segmentLimit = 1000000L;
    private int effort = 5;
    private String deflateHint = KEEP;
    private String modificationTime = KEEP;
    private List passFiles;
    private String unknownAttributeAction = PASS;
    private Map classAttributeActions;
    private Map fieldAttributeActions;
    private Map methodAttributeActions;
    private Map codeAttributeActions;
    private boolean verbose = false;
    private boolean quiet = true;
    private String logFile;

    private Attribute[] unknownAttributeTypes;

    public boolean isRepack() {
        return repack;
    }

    public void setRepack(boolean repack) {
        this.repack = repack;
    }

    public boolean isGzip() {
        return gzip;
    }

    public void setGzip(boolean gzip) {
        this.gzip = gzip;
    }

    public boolean isStripDebug() {
        return stripDebug;
    }

    /**
     * Set strip debug attributes. If true, all debug attributes (i.e.
     * LineNumberTable, SourceFile, LocalVariableTable and
     * LocalVariableTypeTable attributes) are stripped when reading the input
     * class files and not included in the output archive.
     *
     * @param stripDebug
     */
    public void setStripDebug(boolean stripDebug) {
        this.stripDebug = stripDebug;
    }

    public boolean isKeepFileOrder() {
        return keepFileOrder;
    }

    public void setKeepFileOrder(boolean keepFileOrder) {
        this.keepFileOrder = keepFileOrder;
    }

    public long getSegmentLimit() {
        return segmentLimit;
    }

    /**
     * Set the segment limit (equivalent to -S command line option)
     * @param segmentLimit - the limit in bytes
     */
    public void setSegmentLimit(long segmentLimit) {
        this.segmentLimit = segmentLimit;
    }

    public int getEffort() {
        return effort;
    }

    /**
     * Set the compression effort level (0-9, equivalent to -E command line option)
     * @param effort
     */
    public void setEffort(int effort) {
        this.effort = effort;
    }

    public String getDeflateHint() {
        return deflateHint;
    }

    public boolean isKeepDeflateHint() {
        return KEEP.equals(deflateHint);
    }

    public void setDeflateHint(String deflateHint) {
        this.deflateHint = deflateHint;
    }

    public String getModificationTime() {
        return modificationTime;
    }

    public void setModificationTime(String modificationTime) {
        if (!KEEP.equals(modificationTime)
                && !"latest".equals(modificationTime)) {
            throw new IllegalArgumentException(
                    "Bad argument: -m "
                            + modificationTime
                            + " ? transmit modtimes should be either latest or keep (default)");
        }
        this.modificationTime = modificationTime;
    }

    public boolean isPassFile(String passFileName) {
        if (passFiles != null) {
            for (Iterator iterator = passFiles.iterator(); iterator.hasNext();) {
                String pass = (String) iterator.next();
                if (passFileName.equals(pass)) {
                    return true;
                } else if (!pass.endsWith(".class")) { // a whole directory is
                    // passed
                    if (!pass.endsWith("/")) {
                        // Make sure we don't get any false positives (e.g.
                        // exclude "org/apache/harmony/pack" should not match
                        // files under "org/apache/harmony/pack200/")
                        pass = pass + "/";
                    }
                    return passFileName.startsWith(pass);
                }
            }
        }
        return false;
    }

    /**
     * Tell the compressor to pass the file with the given name, or if the name
     * is a directory name all files under that directory will be passed.
     *
     * @param passFileName
     *            the file name
     */
    public void addPassFile(String passFileName) {
        if(passFiles == null) {
            passFiles = new ArrayList();
        }
        String fileSeparator = System.getProperty("file.separator");
        if(fileSeparator.equals("\\")) {
            // Need to escape backslashes for replaceAll(), which uses regex
            fileSeparator += "\\";
        }
        passFileName = passFileName.replaceAll(fileSeparator, "/");
        passFiles.add(passFileName);
    }

    public void removePassFile(String passFileName) {
        passFiles.remove(passFileName);
    }

    public String getUnknownAttributeAction() {
        return unknownAttributeAction;
    }

    /**
     * Tell the compressor what to do if an unknown attribute is encountered
     * @param unknownAttributeAction - the action to perform
     */
    public void setUnknownAttributeAction(String unknownAttributeAction) {
        this.unknownAttributeAction = unknownAttributeAction;
        if (!PASS.equals(unknownAttributeAction)
                && !ERROR.equals(unknownAttributeAction)
                && !STRIP.equals(unknownAttributeAction)) {
            throw new RuntimeException("Incorrect option for -U, "
                    + unknownAttributeAction);
        }
    }

    public Map getClassAttributeActions() {
        return classAttributeActions;
    }

    public void addClassAttributeAction(String attributeName, String action) {
        if(classAttributeActions == null) {
            classAttributeActions = new HashMap();
        }
        classAttributeActions.put(attributeName, action);
    }

    public Map getFieldAttributeActions() {
        return fieldAttributeActions;
    }

    public void addFieldAttributeAction(String attributeName, String action) {
        if(fieldAttributeActions == null) {
            fieldAttributeActions = new HashMap();
        }
        fieldAttributeActions.put(attributeName, action);
    }

    public Map getMethodAttributeActions() {
        return methodAttributeActions;
    }

    public void addMethodAttributeAction(String attributeName, String action) {
        if(methodAttributeActions == null) {
            methodAttributeActions = new HashMap();
        }
        methodAttributeActions.put(attributeName, action);
    }

    public Map getCodeAttributeActions() {
        return codeAttributeActions;
    }

    public void addCodeAttributeAction(String attributeName, String action) {
        if(codeAttributeActions == null) {
            codeAttributeActions = new HashMap();
        }
        codeAttributeActions.put(attributeName, action);
    }

    public boolean isVerbose() {
        return verbose;
    }

    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    public boolean isQuiet() {
        return quiet;
    }

    public void setQuiet(boolean quiet) {
        this.quiet = quiet;
    }

    public String getLogFile() {
        return logFile;
    }

    public void setLogFile(String logFile) {
        this.logFile = logFile;
    }

    private void addOrUpdateAttributeActions(List prototypes, Map attributeActions,
            int tag) {
        if (attributeActions != null) {
            if (attributeActions.size() > 0) {
                String name, action;
                boolean prototypeExists;
                NewAttribute newAttribute;
                for (Iterator iteratorI = attributeActions.keySet().iterator(); iteratorI
                        .hasNext();) {
                    name = (String) iteratorI.next();
                    action = (String) attributeActions.get(name);
                    if (!ERROR.equals(action) && !STRIP.equals(action)
                            && !PASS.equals(action)) {
                        prototypeExists = false;
                        for (Iterator iteratorJ = prototypes.iterator(); iteratorJ
                                .hasNext();) {
                            newAttribute = (NewAttribute) iteratorJ.next();
                            if (newAttribute.type.equals(name)) {
                                // if the attribute exists, update its context
                                newAttribute.addContext(tag);
                                prototypeExists = true;
                                break;
                            }
                            // if no attribute is found, add a new attribute
                            if (!prototypeExists) {
                                newAttribute = new NewAttribute(name, action,
                                        tag);
                                prototypes.add(newAttribute);
                            }
                        }
                    }
                }
            }
        }
    }

    public Attribute[] getUnknownAttributePrototypes() {
        if (unknownAttributeTypes == null) {
            List prototypes = new ArrayList();
            addOrUpdateAttributeActions(prototypes, classAttributeActions,
                    AttributeDefinitionBands.CONTEXT_CLASS);

            addOrUpdateAttributeActions(prototypes, methodAttributeActions,
                    AttributeDefinitionBands.CONTEXT_METHOD);

            addOrUpdateAttributeActions(prototypes, fieldAttributeActions,
                    AttributeDefinitionBands.CONTEXT_FIELD);

            addOrUpdateAttributeActions(prototypes, codeAttributeActions,
                    AttributeDefinitionBands.CONTEXT_CODE);

            unknownAttributeTypes = (Attribute[]) prototypes
                    .toArray(new Attribute[0]);
        }
        return unknownAttributeTypes;
    }

    public String getUnknownClassAttributeAction(String type) {
        String action = (String) classAttributeActions.get(type);
        if(action == null) {
            action = unknownAttributeAction;
        }
        return action;
    }

    public String getUnknownMethodAttributeAction(String type) {
        String action = (String) methodAttributeActions.get(type);
        if(action == null) {
            action = unknownAttributeAction;
        }
        return action;
    }

    public String getUnknownFieldAttributeAction(String type) {
        String action = (String) fieldAttributeActions.get(type);
        if(action == null) {
            action = unknownAttributeAction;
        }
        return action;
    }

    public String getUnknownCodeAttributeAction(String type) {
        String action = (String) codeAttributeActions.get(type);
        if(action == null) {
            action = unknownAttributeAction;
        }
        return action;
    }

}
