/*
 *
 *  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.tools.codecoverage.reporter.swf;

import org.apache.flex.abc.ABCConstants;
import org.apache.flex.abc.Pool;
import org.apache.flex.abc.instructionlist.InstructionList;
import org.apache.flex.abc.semantics.ExceptionInfo;
import org.apache.flex.abc.semantics.Instruction;
import org.apache.flex.abc.semantics.Label;
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.visitors.IMethodBodyVisitor;
import org.apache.flex.abc.visitors.IMethodVisitor;
import org.apache.flex.abc.visitors.ITraitsVisitor;
import org.apache.flex.abc.visitors.NilABCVisitor;
import org.apache.flex.abc.visitors.NilVisitors;
import org.apache.flex.tools.codecoverage.reporter.CoverageData;

/**
 * Gather all the debug lines and method in a SWF file. 
 * Look for debug_file and debug_line op codes and record them so we know all
 * of possible lines in the SWF that can be executed.
 *
 */
public class DebugLineVisitor extends NilABCVisitor
{

    private final Pool<String> stringPool = new Pool<String>(Pool.DefaultType.HasDefaultZero);
    private final CoverageData coverageData;

    /**
     * Constructor
     * 
     * @param coverageData The coverage data where debug lines will be added
     * as unexecuted lines. If a line is already in the coverage data and is
     * marked as executed, then it will remain an executed line.
     */
    public DebugLineVisitor(final CoverageData coverageData)
    {
        this.coverageData = coverageData;
    }

    @Override
    public IMethodVisitor visitMethod(MethodInfo minfo)
    {
        return new MethodVisitor();
    }

    @Override
    public void visitPooledString(String s)
    {
        stringPool.add(s);
    }

    /**
     * Visit all the methods in the ABC.
     */
    private class MethodVisitor implements IMethodVisitor
    {
        @Override
        public void visitEnd()
        {
        }

        @Override
        public void visit()
        {
        }

        @Override
        public IMethodBodyVisitor visitBody(MethodBodyInfo mbInfo)
        {
            return new MethodBodyVisitor(mbInfo);
        }
    }
    
    /**
     * Visit all the method bodies in the ABC.
     */
    private class MethodBodyVisitor implements IMethodBodyVisitor
    {
        private final MethodBodyInfo mbInfo;
        private String currentFilename;
        
        public MethodBodyVisitor(MethodBodyInfo mbInfo)
        {
            this.mbInfo = mbInfo;
        }

        @Override
        public void visitEnd()
        {
        }

        @Override
        public void labelCurrent(Label l)
        {
        }

        @Override
        public void labelNext(Label l)
        {
        }

        @Override
        public void visit()
        {
        }

        @Override
        public int visitException(Label from, Label to, Label target, 
                Name exception_type, Name catch_var)
        {
            return  mbInfo.addExceptionInfo(new ExceptionInfo(from, to, target,
                        exception_type, catch_var));
        }

        @Override
        public void visitInstructionList(InstructionList new_list)
        {
            for (Instruction inst : new_list.getInstructions())
            {
                int opcode = inst.getOpcode();
                assert opcode != ABCConstants.OP_debugfile && 
                        opcode != ABCConstants.OP_debugline :
                        "unexpected debug opcode";
            }
        }

        @Override
        public void visitInstruction(int opcode)
        {
            assert opcode != ABCConstants.OP_debugfile && 
                    opcode != ABCConstants.OP_debugline :
                    "unexpected debug opcode";
        }

        @Override
        public void visitInstruction(int opcode, int immediate_operand)
        {
            if (opcode == ABCConstants.OP_debugfile)
            {
                recordDebugFile(immediate_operand);
            }
            else if (opcode == ABCConstants.OP_debugline)
            {
                recordDebugLine(immediate_operand);
            }
        }

        @Override
        public void visitInstruction(int opcode, Object[] operands)
        {
            assert opcode != ABCConstants.OP_debugfile && 
                    opcode != ABCConstants.OP_debugline :
                    "unexpected debug opcode";
        }

        @Override
        public void visitInstruction(int opcode, Object single_operand)
        {
            assert opcode != ABCConstants.OP_debugline :
                    "unexpected debug opcode";

            if (opcode == ABCConstants.OP_debugfile)
                recordDebugFile((String)single_operand);
        }

        @Override
        public void visitInstruction(Instruction instruction)
        {
            int opcode = instruction.getOpcode();
            assert opcode != ABCConstants.OP_debugfile && 
                    opcode != ABCConstants.OP_debugline :
                    "unexpected debug opcode";
        }

        @Override
        public ITraitsVisitor visitTraits()
        {
            return NilVisitors.NIL_TRAITS_VISITOR;
        }

        /**
         * Record a debugfile string
         * 
         * @param filenameIndex Index of filename in the string pool.
         */
        private void recordDebugFile(final int filenameIndex)
        {
            recordDebugFile(stringPool.getValues().get(filenameIndex));
        }

        /**
         * Set the filename in the context for debug lines that
         * come after it.
         * 
         * @param filename The debugfile filename.
         */
        private void recordDebugFile(final String filename)
        {
            currentFilename = filename;
        }
        
        /**
         * Record a debug line into the coverage data.
         * 
         * @param lineNumber The line number of the debug line in 
         * the file that is set by the last debugfile opcode.
         */
        private void recordDebugLine(final int lineNumber)
        {
            assert currentFilename != null : 
                "currentFilename must have been set by a debugFile instruction";

            String methodName =  mbInfo.getMethodInfo().getMethodName(); 
            coverageData.addLine(currentFilename, lineNumber, methodName);
        }
    }
}
