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

import org.apache.flex.abc.diagnostics.AbstractDiagnosticVisitor;
import org.apache.flex.abc.graph.IFlowgraph;
import org.apache.flex.abc.graph.IBasicBlock;
import org.apache.flex.abc.instructionlist.InstructionList;
import org.apache.flex.abc.optimize.DeadCodeFilter;
import org.apache.flex.abc.optimize.PeepholeOptimizerMethodBodyVisitor;
import org.apache.flex.abc.semantics.ClassInfo;
import org.apache.flex.abc.semantics.InstanceInfo;
import org.apache.flex.abc.semantics.Instruction;
import org.apache.flex.abc.semantics.Label;
import org.apache.flex.abc.semantics.Metadata;
import org.apache.flex.abc.semantics.MethodBodyInfo;
import org.apache.flex.abc.semantics.MethodInfo;
import org.apache.flex.abc.semantics.Name;
import org.apache.flex.abc.semantics.Namespace;
import org.apache.flex.abc.semantics.Nsset;
import org.apache.flex.abc.visitors.DelegatingClassVisitor;
import org.apache.flex.abc.visitors.DelegatingMetadataVisitor;
import org.apache.flex.abc.visitors.DelegatingMethodBodyVisitor;
import org.apache.flex.abc.visitors.DelegatingMethodVisitor;
import org.apache.flex.abc.visitors.DelegatingScriptVisitor;
import org.apache.flex.abc.visitors.DelegatingTraitVisitor;
import org.apache.flex.abc.visitors.DelegatingTraitsVisitor;
import org.apache.flex.abc.visitors.IABCVisitor;
import org.apache.flex.abc.visitors.IClassVisitor;
import org.apache.flex.abc.visitors.IDiagnosticsVisitor;
import org.apache.flex.abc.visitors.IMetadataVisitor;
import org.apache.flex.abc.visitors.IMethodBodyVisitor;
import org.apache.flex.abc.visitors.IMethodVisitor;
import org.apache.flex.abc.visitors.IScriptVisitor;
import org.apache.flex.abc.visitors.ITraitVisitor;
import org.apache.flex.abc.visitors.ITraitsVisitor;
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.problems.UnreachableBlockProblem;

import java.io.File;
import java.util.Collection;

/**
 * The ABCLinker links a sequence of ABC blocks into a single ABC block,
 * and contains utility methods to perform various transformations on the ABC.
 */
public class ABCLinker
{
    public static byte[] linkABC(Iterable<byte[]> inputABCs, int majorVersion, int minorVersion, ABCLinkerSettings settings) throws Exception
    {
        ABCEmitter emitter = new ABCEmitter();
        // ABCs from 4.5 may have non-sensical jumps past the end of a method
        // so allow those, instead of throwin java exceptions
        emitter.setAllowBadJumps(true);
        emitter.visit(majorVersion, minorVersion);
        for (byte[] inputABC : inputABCs)
        {
            ABCParser abcParser = new ABCParser(inputABC);
            abcParser.parseABC(new LinkingVisitor(emitter, settings));
        }
        emitter.visitEnd();
        return emitter.emit();
    }

    public static class ABCLinkerSettings
    {
        private boolean optimize = false;
        private boolean enableInlining = false;
        private boolean stripDebug = false;
        private boolean stripFileAttributeFromGotoDefinitionHelp = false;
        private boolean stripGotoDefinitionHelp = false;
        private boolean removeDeadCode = false;
        private Collection<String> meta_names = null;
        @SuppressWarnings("unused")
        private int minorVersion = ABCConstants.VERSION_ABC_MINOR_FP10;
        @SuppressWarnings("unused")
        private int majorVersion = ABCConstants.VERSION_ABC_MAJOR_FP10;
        private Collection<ICompilerProblem> problems;

        /**
         * Tell the linker whether it should run the peephole optimizer defaults
         * to false
         * 
         * @param b true if the ABCs should be optimized
         */
        public void setOptimize(boolean b)
        {
            optimize = b;
        }

        /**
         * Tell the linker whether it should enable inlining of functions.
         * defaults to false
         * @param b true if the functions should be inlined
         */
        public void setEnableInlining(boolean b)
        {
            enableInlining = b;
        }

        /**
         * Tell the linker whether is should strip out debug opcodes defaults to
         * false
         * 
         * @param b true if the ABCs should have the debug opcodes stripped out
         */
        public void setStripDebugOpcodes(boolean b)
        {
            stripDebug = b;
        }

        /**
         * Tell the linker which metadata names it should keep. If null, it will
         * keep them all except for "go to definition help" which is control by
         * the stripGotoDefinitionHelp flag. Defaults to null.
         * 
         * @param metadata_names A collection of metadata names that the linker
         * will keep.
         */
        public void setKeepMetadata(Collection<String> metadata_names)
        {
            meta_names = metadata_names;
        }

        /**
         * @return true if we should be stripping some metadata
         */
        boolean shouldStripMetadata()
        {
            return meta_names != null || stripGotoDefinitionHelp ||
                   stripFileAttributeFromGotoDefinitionHelp;
        }

        public void setTargetABCVersion(int major, int minor)
        {
            this.majorVersion = major;
            this.minorVersion = minor;
        }

        /**
         * If the metadata to keep is null, this flag determines if
         * "go to definition help" metadata is removed.
         * 
         * @param stripGotoDefinitionHelp <code>true</code> to strip the metadata,
         * <code>false</code> to leave it.
         */
        public void setStripGotoDefinitionHelp(boolean stripGotoDefinitionHelp)
        {
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
        }

        /**
         * If "go to definition help" meta is being kept, this flag determines
         * if we should strip the file attribute from the metadata.
         * 
         * @param stripFileAttributeFromGotoDefinitionHelp <code>true</code> to strip
         * the file attribute, <code>false</code> to leave it.
         */
        public void setStripFileAttributeFromGotoDefinitionHelp(boolean stripFileAttributeFromGotoDefinitionHelp)
        {
            this.stripFileAttributeFromGotoDefinitionHelp = stripFileAttributeFromGotoDefinitionHelp;
        }

        /**
         * Enable or disable the DeadCodeFilter optimization step.
         * @param removeDeadCode true if the DeadCodeFilter should be run.
         */
        public void setRemoveDeadCode(final boolean removeDeadCode)
        {
            this.removeDeadCode = removeDeadCode;
        }

        /**
         * Set a problems collection for errors or warnings during link.
         * @param problems the problems collection to receive errors or warnings.
         */
        public void setProblemsCollection(Collection<ICompilerProblem> problems)
        {
            this.problems = problems;
        }
    }

    /**
     * IMethodBodyVisitor implementation that will strip out Debug opcodes
     */
    private static final class DebugStrippingMethodBodyVisitor extends DelegatingMethodBodyVisitor
    {
        public DebugStrippingMethodBodyVisitor(IMethodBodyVisitor delegate)
        {
            super(delegate);
        }

        // flag to keep track of if the last instruction was one we stripped out
        // needed for figuring out where some labels land - see labelCurrent()
        private boolean strippedLastInstruction;

        /**
         * Determine if the opcode should be stripped out, or passed along to
         * the next visitor. This also flags whether the opcode was stripped or
         * not, so if you're calling this make sure you do what it tells you to
         * 
         * @param opcode The instruction to check
         * @return true if the instruction should be stripped out.
         */
        private boolean stripInstruction(int opcode)
        {
            switch (opcode)
            {
                case ABCConstants.OP_debug:
                case ABCConstants.OP_debugfile:
                case ABCConstants.OP_debugline:
                    strippedLastInstruction = true;
                    break;
                default:
                    strippedLastInstruction = false;
                    break;
            }
            return strippedLastInstruction;
        }

        @Override
        public void visitInstructionList(InstructionList new_list)
        {
            // for the delegates that run after this IVisitor, they will be processing
            // a new copy of the instruction list, which will not have the debug opcodes
            InstructionList strippedInstructionList = new InstructionList(new_list.size());
            for (Instruction inst : new_list.getInstructions())
            {
                if (!stripInstruction(inst.getOpcode()))
                    strippedInstructionList.addInstruction(inst);
            }
            super.visitInstructionList(strippedInstructionList);
        }

        @Override
        public void visitInstruction(int opcode)
        {

            if (stripInstruction(opcode))
                return;
            super.visitInstruction(opcode);
        }

        @Override
        public void visitInstruction(int opcode, int immediate_operand)
        {
            if (stripInstruction(opcode))
                return;

            super.visitInstruction(opcode, immediate_operand);
        }

        @Override
        public void visitInstruction(int opcode, Object[] operands)
        {
            if (stripInstruction(opcode))
                return;
            super.visitInstruction(opcode, operands);
        }

        @Override
        public void visitInstruction(int opcode, Object single_operand)
        {
            if (stripInstruction(opcode))
                return;
            super.visitInstruction(opcode, single_operand);
        }

        @Override
        public void visitInstruction(Instruction instruction)
        {
            if (stripInstruction(instruction.getOpcode()))
                return;
            super.visitInstruction(instruction);
        }

        @Override
        public void labelCurrent(Label l)
        {
            // if we're trying to label a debug instruction that got stripped out
            // then we really want to label the next instruction, and not whatever the
            // last instruction happens to be.
            // We only do this if the label may target a non-executable instruction - this
            // is because we are stripping non executable instructions here - if the label must
            // target an executable instruction, then the behavior of labelCurrent is correct -
            // it would have walked back over the instructions until it found the first non-executable
            // instruction.
            if (strippedLastInstruction && !l.targetMustBeExecutable())
                super.labelNext(l);
            else
                super.labelCurrent(l);
        }
    }

    /**
     * IMethodVisitor that will create a DebugStrippingMethodBodyVisitor - used
     * when you want to remove debug opcodes from the method body.
     */
    private static class DebugStrippingMethodVisitor extends DelegatingMethodVisitor
    {
        public DebugStrippingMethodVisitor(IMethodVisitor delegate)
        {
            super(delegate);
        }

        @Override
        public IMethodBodyVisitor visitBody(MethodBodyInfo mbi)
        {
            return new DebugStrippingMethodBodyVisitor(super.visitBody(mbi));
        }
    }

    /**
     * IMethodVisitor that will create an PeepholeOptimizerMethodBodyVisitor for
     * the method body - used when you want to run the peephole optimizer for
     * the method body
     */
    private static class OptimizingMethodVisitor extends DelegatingMethodVisitor
    {
        public OptimizingMethodVisitor(IMethodVisitor delegate, Collection<ICompilerProblem> problems, final boolean removeDeadCode)
        {
            super(delegate);
            this.problems = problems;
            this.removeDeadCode = removeDeadCode;
        }

        /**
         * Sink for problems generated during this phase.
         */
        final Collection<ICompilerProblem> problems;

        /**
         * When true, run a DeadCodeFilter as part of the optimization pipeline.
         */
        final boolean removeDeadCode;

        @Override
        public IMethodBodyVisitor visitBody(MethodBodyInfo mbi)
        {
            //  Set up the optimizer pipeline.
            IMethodBodyVisitor delegate = super.visitBody(mbi);

            if ( removeDeadCode )
            {
                IDiagnosticsVisitor diagnostics = new AbstractDiagnosticVisitor()
                {
                    @Override
                    public void unreachableBlock(MethodBodyInfo methodBodyInfo, IFlowgraph cfg, IBasicBlock block)
                    {
                        if ( problems != null )
                        {
                            String fileName = cfg.findSourcePath(block);

                            if ( fileName != null && new File(fileName).isFile() )
                                problems.add(new UnreachableBlockProblem(fileName, cfg.findLineNumber(block)));
                        }
                    }
                };
                delegate = new DeadCodeFilter(mbi, delegate, diagnostics);
            }

            return new PeepholeOptimizerMethodBodyVisitor(delegate);
        }
    }

    /**
     * IScriptVisitor that will create a MetadataStrippingTraitsVisitor for the
     * script traits
     */
    private static class MetadataStrippingScriptVisitor extends DelegatingScriptVisitor
    {
        MetadataStrippingScriptVisitor(IScriptVisitor d, Collection<String> meta_names,
                                       boolean stripGotoDefinitionHelp,
                                       boolean stripFileAttribute)
        {
            super(d);
            this.meta_names = meta_names;
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
            this.stripFileAttribute = stripFileAttribute;
        }

        private Collection<String> meta_names;
        private boolean stripGotoDefinitionHelp;
        private boolean stripFileAttribute;

        @Override
        public ITraitsVisitor visitTraits()
        {
            return new MetadataStrippingTraitsVisitor(super.visitTraits(), meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }

    }

    /**
     * IClassVisitor that will create a MetadataStrippingTraitsVisitor for the
     * class and instance traits.
     */
    private static class MetadataStrippingClassVisitor extends DelegatingClassVisitor
    {
        MetadataStrippingClassVisitor(IClassVisitor d, Collection<String> meta_names,
                                      boolean stripGotoDefinitionHelp,
                                      boolean stripFileAttribute)
        {
            super(d);
            this.meta_names = meta_names;
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
            this.stripFileAttribute = stripFileAttribute;
        }

        private Collection<String> meta_names;
        private boolean stripGotoDefinitionHelp;
        private boolean stripFileAttribute;

        @Override
        public ITraitsVisitor visitClassTraits()
        {
            return new MetadataStrippingTraitsVisitor(super.visitClassTraits(), meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }

        @Override
        public ITraitsVisitor visitInstanceTraits()
        {
            return new MetadataStrippingTraitsVisitor(super.visitInstanceTraits(), meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }
    }

    /**
     * ITraitVisitor that will create a metadata visitor that will strip out some
     * metadata.
     */
    private static class MetadataStrippingTraitVisitor extends DelegatingTraitVisitor
    {
        MetadataStrippingTraitVisitor(ITraitVisitor d, Collection<String> meta_names,
                                      boolean stripGotoDefinitionHelp,
                                      boolean stripFileAttribute)
        {
            super(d);
            this.meta_names = meta_names;
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
            this.stripFileAttribute = stripFileAttribute;
        }

        private Collection<String> meta_names;
        private boolean stripGotoDefinitionHelp;
        private boolean stripFileAttribute;

        @Override
        public IMetadataVisitor visitMetadata(int count)
        {
            return new MetadataStrippingVisitor(super.visitMetadata(count), meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }
    }

    /**
     * IMetadataVisitor that will only emit certain metadata, and will strip out
     * the rest of the metadata. If no metadata is supposed to be stripped, then
     * you shouldn't create one of these
     */
    private static class MetadataStrippingVisitor extends DelegatingMetadataVisitor
    {

        /**
         * Constants for removing the __go_to_definition_help and __go_to_definition_ctor
         * help that get injected for go to definition support
         */
        private static final String GO_TO_DEFINITION_HELP = "__go_to_definition_help";
        private static final String GO_TO_DEFINITION_CTOR_HELP = "__go_to_ctor_definition_help";
        private static final String GO_TO_DEFINITION_HELP_FILE = "file";

        /**
         * If the meta tag is "__go_to_ctor_definition_help" or
         * "__go_to_definition_help", strip off the "file" attribute.
         * 
         * @param metadata The data to strip the "file" attribute from.
         */
        static Metadata stripFileAttributeFromGotoDefinitionHelp(Metadata metadata)
        {
            String name = metadata.getName();
            if (GO_TO_DEFINITION_HELP.equals(name) ||
                GO_TO_DEFINITION_CTOR_HELP.equals(name))
            {
                metadata = removeKey(metadata, GO_TO_DEFINITION_HELP_FILE);
            }

            return metadata;
        }

        /**
         * Remove a key from this metadata.
         * 
         * @param key The key to remove. May not be null.
         */
        static Metadata removeKey(Metadata metadata, String key)
        {
            assert metadata != null;
            assert key != null;

            String[] keys = metadata.getKeys();
            for (int i = 0; i < keys.length; i++)
            {
                if (key.equals(keys[i]))
                {
                    String[] values = metadata.getValues();
                    String[] newKeys = new String[keys.length - 1];
                    String[] newValues = new String[keys.length - 1];

                    // Copy attributes up to found attribute.
                    if (i > 0)
                    {
                        System.arraycopy(keys, 0, newKeys, 0, i);
                        System.arraycopy(values, 0, newValues, 0, i);

                    }

                    // Copy attributes after the found attribute.
                    if (i < (keys.length - 1))
                    {
                        System.arraycopy(keys, i + 1, newKeys, i,
                                keys.length - i - 1);
                        System.arraycopy(values, i + 1, newValues, i,
                                keys.length - i - 1);
                    }

                    metadata = new Metadata(metadata.getName(), newKeys, newValues);
                    break;
                }
            }

            return metadata;
        }

        /**
         * Constructor
         * 
         * @param d the delegate visitor to wrap
         * @param meta_names the names of the metadata which should be emitted.
         * If null, all the names are emitted except for "go to definition help"
         * metadata which is controlled by the stripGotoDefinitionHelp parameter
         * and stripFileAttribute parameter.
         * @param stripGotoDefinitionHelp true if "go to definition help"
         * metadata should be stripped out, false otherwise.
         * @param stripFileAttribute true if the "file" attribute of the goto
         * definition metadata should be stripped.
         */
        MetadataStrippingVisitor(IMetadataVisitor d, Collection<String> meta_names,
                                 boolean stripGotoDefinitionHelp,
                                 boolean stripFileAttribute)
        {
            super(d);
            this.metaNames = meta_names;
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
            this.stripFileAttribute = stripFileAttribute;
        }

        private Collection<String> metaNames;
        private boolean stripGotoDefinitionHelp;
        private boolean stripFileAttribute;

        @Override
        public void visit(Metadata md)
        {
            if (shouldKeep(md))
            {
                if (!stripGotoDefinitionHelp && stripFileAttribute)
                    md = stripFileAttributeFromGotoDefinitionHelp(md);
                super.visit(md);
            }
            return;
        }

        boolean shouldKeep(Metadata md)
        {
            if (metaNames == null)
            {
                if (GO_TO_DEFINITION_HELP.equals(md.getName()) ||
                    GO_TO_DEFINITION_CTOR_HELP.equals(md.getName()))
                {
                    return !stripGotoDefinitionHelp;
                }

                return true;
            }
            return metaNames.contains(md.getName());
        }
    }

    /**
     * ITraitsVisitor that will wrap any generated ITraitVisitor in a
     * MetadataStrippingTraitVisitor
     */
    private static class MetadataStrippingTraitsVisitor extends DelegatingTraitsVisitor
    {
        MetadataStrippingTraitsVisitor(ITraitsVisitor d, Collection<String> meta_names,
                                       boolean stripGotoDefinitionHelp,
                                       boolean stripFileAttribute)
        {
            super(d);
            this.meta_names = meta_names;
            this.stripGotoDefinitionHelp = stripGotoDefinitionHelp;
            this.stripFileAttribute = stripFileAttribute;
        }

        private Collection<String> meta_names;
        private boolean stripGotoDefinitionHelp;
        private boolean stripFileAttribute;

        @Override
        public ITraitVisitor visitSlotTrait(int kind, Name name, int slot_id, Name slot_type, Object slot_value)
        {
            return new MetadataStrippingTraitVisitor(
                    super.visitSlotTrait(kind, name, slot_id, slot_type, slot_value),
                    meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }

        @Override
        public ITraitVisitor visitClassTrait(int kind, Name name, int slot_id, ClassInfo clazz)
        {
            return new MetadataStrippingTraitVisitor(
                    super.visitClassTrait(kind, name, slot_id, clazz),
                    meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }

        @Override
        public ITraitVisitor visitMethodTrait(int kind, Name name, int disp_id, MethodInfo method)
        {
            return new MetadataStrippingTraitVisitor(
                    super.visitMethodTrait(kind, name, disp_id, method),
                    meta_names,
                    stripGotoDefinitionHelp,
                    stripFileAttribute);
        }
    }

    /**
     * IABCVisitor implementation to do various transformations on an ABC file -
     * stripping debug opcodes, optimizing, etc.
     */
    private static class LinkingVisitor implements IABCVisitor
    {
        public LinkingVisitor(ABCEmitter delegate, ABCLinkerSettings linkSettings)
        {
            this.delegate = delegate;
            this.settings = linkSettings;
        }

        private final ABCEmitter delegate;
        private final ABCLinkerSettings settings;

        @Override
        public void visit(int major_version, int minor_version)
        {
            // Don't call into the delegate, the linker has done that!
        }

        @Override
        public void visitEnd()
        {
            // Do nothing... This will be called once by the linker on the
            // delegate.
        }

        @Override
        public IScriptVisitor visitScript()
        {
            IScriptVisitor sv = delegate.visitScript();
            if (settings.shouldStripMetadata())
                sv = new MetadataStrippingScriptVisitor(sv, settings.meta_names,
                        settings.stripGotoDefinitionHelp,
                        settings.stripFileAttributeFromGotoDefinitionHelp);
            return sv;
        }

        @Override
        public IClassVisitor visitClass(InstanceInfo iinfo, ClassInfo cinfo)
        {
            IClassVisitor cv = delegate.visitClass(iinfo, cinfo);
            if (settings.shouldStripMetadata())
                cv = new MetadataStrippingClassVisitor(cv, settings.meta_names,
                        settings.stripGotoDefinitionHelp,
                        settings.stripFileAttributeFromGotoDefinitionHelp);
            return cv;
        }

        @Override
        public IMethodVisitor visitMethod(MethodInfo minfo)
        {
            IMethodVisitor mv = delegate.visitMethod(minfo);
            if (settings.optimize)
                mv = new OptimizingMethodVisitor(mv, settings.problems, settings.removeDeadCode);

            // Run the debug stripping visitor first, so the debug
            // instructions won't confuse the peephole optimizer
            // building a chain of visitors, so the debug stripping will
            // wrap the optimizing visitor
            if (settings.stripDebug)
                mv = new DebugStrippingMethodVisitor(mv);

            return mv;
        }

        @Override
        public void visitPooledInt(Integer i)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledUInt(Long l)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledDouble(Double d)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledString(String s)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledNamespace(Namespace ns)
        {
            if (settings.enableInlining)
                ns.setMergePrivateNamespaces(true);
        }

        @Override
        public void visitPooledNsSet(Nsset nss)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledName(Name n)
        {
            // emitter automatically pools values.
        }

        @Override
        public void visitPooledMetadata(Metadata md)
        {
            // emitter automatically pools values.
        }
    }
}
