/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed 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 com.android.dx.command.dump;

import com.android.dx.cf.code.ConcreteMethod;
import com.android.dx.cf.code.Ropper;
import com.android.dx.cf.iface.Member;
import com.android.dx.cf.iface.Method;
import com.android.dx.rop.code.RopMethod;
import com.android.dx.rop.code.TranslationAdvice;
import com.android.dx.rop.code.DexTranslationAdvice;
import com.android.dx.rop.code.AccessFlags;
import com.android.dx.ssa.DeadCodeRemover;
import com.android.dx.ssa.PhiTypeResolver;
import com.android.dx.ssa.SsaBasicBlock;
import com.android.dx.ssa.SsaConverter;
import com.android.dx.ssa.SsaInsn;
import com.android.dx.ssa.SsaMethod;
import com.android.dx.ssa.Optimizer;
import com.android.dx.ssa.ConstCollector;
import com.android.dx.ssa.SCCP;
import com.android.dx.ssa.LiteralOpUpgrader;
import com.android.dx.ssa.back.SsaToRop;
import com.android.dx.util.ByteArray;
import com.android.dx.util.Hex;
import com.android.dx.util.IntList;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.EnumSet;

/**
 * Dumper for the SSA-translated blocks of a method.
 */
public class SsaDumper extends BlockDumper {
    /**
     * Does the dump.
     * 
     * @param bytes {@code non-null;} bytes of the original class file
     * @param out {@code non-null;} where to dump to
     * @param filePath the file path for the class, excluding any base
     * directory specification
     * @param args commandline parsedArgs
     */
    public static void dump(byte[] bytes, PrintStream out,
            String filePath, Args args) {
        SsaDumper sd = new SsaDumper(bytes, out, filePath, args);
        sd.dump();
    }

    /**
     * Constructs an instance.
     * 
     * @param bytes {@code non-null;} bytes of the original class file
     * @param out {@code non-null;} where to dump to
     * @param filePath the file path for the class, excluding any base
     * directory specification
     * @param args commandline parsedArgs
     */
    private SsaDumper(byte[] bytes, PrintStream out, String filePath,
            Args args) {
        super(bytes, out, filePath, true, args);
    }

    /** {@inheritDoc} */
    @Override
    public void endParsingMember(ByteArray bytes, int offset, String name,
            String descriptor, Member member) {
        if (!(member instanceof Method)) {
            return;
        }

        if (!shouldDumpMethod(name)) {
            return;
        }

        ConcreteMethod meth =
            new ConcreteMethod((Method) member, classFile, true, true);
        TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
        RopMethod rmeth = Ropper.convert(meth, advice);
        SsaMethod ssaMeth = null;
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        int paramWidth = computeParamWidth(meth, isStatic);

        if (args.ssaStep == null) {
            ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth,
                    paramWidth, isStatic, true, advice,
                    EnumSet.allOf(Optimizer.OptionalStep.class));
        } else if ("edge-split".equals(args.ssaStep)) {
            ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth,
                    isStatic, true, advice);
        } else if ("phi-placement".equals(args.ssaStep)) {
            ssaMeth = Optimizer.debugPhiPlacement(
                    rmeth, paramWidth, isStatic, true, advice);
        } else if ("renaming".equals(args.ssaStep)) {
            ssaMeth = Optimizer.debugRenaming(
                    rmeth, paramWidth, isStatic, true, advice);
        } else if ("dead-code".equals(args.ssaStep)) {
            ssaMeth = Optimizer.debugDeadCodeRemover(
                    rmeth, paramWidth, isStatic,true, advice);
        }

        StringBuffer sb = new StringBuffer(2000);

        sb.append("first ");
        sb.append(Hex.u2(
                ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex())));
        sb.append('\n');

        ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
        ArrayList<SsaBasicBlock> sortedBlocks = 
            (ArrayList<SsaBasicBlock>) blocks.clone();
        Collections.sort(sortedBlocks, SsaBasicBlock.LABEL_COMPARATOR);
        
        for (SsaBasicBlock block : sortedBlocks) {
            sb.append("block ")
                    .append(Hex.u2(block.getRopLabel())).append('\n');

            BitSet preds = block.getPredecessors();

            for (int i = preds.nextSetBit(0); i >= 0;
                 i = preds.nextSetBit(i+1)) {
                sb.append("  pred ");
                sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(i)));
                sb.append('\n');
            }

            sb.append("  live in:" + block.getLiveInRegs());
            sb.append("\n");

            for (SsaInsn insn : block.getInsns()) {
                sb.append("  ");
                sb.append(insn.toHuman());
                sb.append('\n');
            }

            if (block.getSuccessors().cardinality() == 0) {
                sb.append("  returns\n");
            } else {
                int primary = block.getPrimarySuccessorRopLabel();

                IntList succLabelList = block.getRopLabelSuccessorList();

                int szSuccLabels = succLabelList.size();

                for (int i = 0; i < szSuccLabels; i++) {
                    sb.append("  next ");
                    sb.append(Hex.u2(succLabelList.get(i)));

                    if (szSuccLabels != 1 && primary == succLabelList.get(i)) {
                        sb.append(" *");                        
                    }
                    sb.append('\n');
                }
            }

            sb.append("  live out:" + block.getLiveOutRegs());
            sb.append("\n");
        }

        suppressDump = false;
        setAt(bytes, 0);
        parsed(bytes, 0, bytes.size(), sb.toString());
        suppressDump = true;
    }
}
