/*
 * Copyright (C) 2008 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.dex.file;

import com.android.dx.dex.code.CatchHandlerList;
import com.android.dx.dex.code.CatchTable;
import com.android.dx.dex.code.DalvCode;
import com.android.dx.rop.cst.CstType;
import com.android.dx.rop.type.Type;
import com.android.dx.util.AnnotatedOutput;
import com.android.dx.util.ByteArrayAnnotatedOutput;
import com.android.dx.util.Hex;

import java.io.PrintWriter;
import java.util.Map;
import java.util.TreeMap;

/**
 * List of exception handlers (tuples of covered range, catch type,
 * handler address) for a particular piece of code. Instances of this
 * class correspond to a {@code try_item[]} and a
 * {@code catch_handler_item[]}.
 */
public final class CatchStructs {
    /**
     * the size of a {@code try_item}: a {@code uint}
     * and two {@code ushort}s
     */
    private static final int TRY_ITEM_WRITE_SIZE = 4 + (2 * 2);

    /** {@code non-null;} code that contains the catches */
    private final DalvCode code;

    /**
     * {@code null-ok;} the underlying table; set in
     * {@link #finishProcessingIfNecessary}
     */
    private CatchTable table;

    /**
     * {@code null-ok;} the encoded handler list, if calculated; set in
     * {@link #encode}
     */
    private byte[] encodedHandlers;

    /**
     * length of the handlers header (encoded size), if known; used for
     * annotation
     */
    private int encodedHandlerHeaderSize;

    /**
     * {@code null-ok;} map from handler lists to byte offsets, if calculated; set in
     * {@link #encode}
     */
    private TreeMap<CatchHandlerList, Integer> handlerOffsets;

    /**
     * Constructs an instance.
     *
     * @param code {@code non-null;} code that contains the catches
     */
    public CatchStructs(DalvCode code) {
        this.code = code;
        this.table = null;
        this.encodedHandlers = null;
        this.encodedHandlerHeaderSize = 0;
        this.handlerOffsets = null;
    }

    /**
     * Finish processing the catches, if necessary.
     */
    private void finishProcessingIfNecessary() {
        if (table == null) {
            table = code.getCatches();
        }
    }

    /**
     * Gets the size of the tries list, in entries.
     *
     * @return {@code >= 0;} the tries list size
     */
    public int triesSize() {
        finishProcessingIfNecessary();
        return table.size();
    }

    /**
     * Does a human-friendly dump of this instance.
     *
     * @param out {@code non-null;} where to dump
     * @param prefix {@code non-null;} prefix to attach to each line of output
     */
    public void debugPrint(PrintWriter out, String prefix) {
        annotateEntries(prefix, out, null);
    }

    /**
     * Encodes the handler lists.
     *
     * @param file {@code non-null;} file this instance is part of
     */
    public void encode(DexFile file) {
        finishProcessingIfNecessary();

        TypeIdsSection typeIds = file.getTypeIds();
        int size = table.size();

        handlerOffsets = new TreeMap<CatchHandlerList, Integer>();

        /*
         * First add a map entry for each unique list. The tree structure
         * will ensure they are sorted when we reiterate later.
         */
        for (int i = 0; i < size; i++) {
            handlerOffsets.put(table.get(i).getHandlers(), null);
        }

        if (handlerOffsets.size() > 65535) {
            throw new UnsupportedOperationException(
                    "too many catch handlers");
        }

        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();

        // Write out the handlers "header" consisting of its size in entries.
        encodedHandlerHeaderSize =
            out.writeUnsignedLeb128(handlerOffsets.size());

        // Now write the lists out in order, noting the offset of each.
        for (Map.Entry<CatchHandlerList, Integer> mapping :
                 handlerOffsets.entrySet()) {
            CatchHandlerList list = mapping.getKey();
            int listSize = list.size();
            boolean catchesAll = list.catchesAll();

            // Set the offset before we do any writing.
            mapping.setValue(out.getCursor());

            if (catchesAll) {
                // A size <= 0 means that the list ends with a catch-all.
                out.writeSignedLeb128(-(listSize - 1));
                listSize--;
            } else {
                out.writeSignedLeb128(listSize);
            }

            for (int i = 0; i < listSize; i++) {
                CatchHandlerList.Entry entry = list.get(i);
                out.writeUnsignedLeb128(
                        typeIds.indexOf(entry.getExceptionType()));
                out.writeUnsignedLeb128(entry.getHandler());
            }

            if (catchesAll) {
                out.writeUnsignedLeb128(list.get(listSize).getHandler());
            }
        }

        encodedHandlers = out.toByteArray();
    }

    /**
     * Gets the write size of this instance, in bytes.
     *
     * @return {@code >= 0;} the write size
     */
    public int writeSize() {
        return (triesSize() * TRY_ITEM_WRITE_SIZE) +
                + encodedHandlers.length;
    }

    /**
     * Writes this instance to the given stream.
     *
     * @param file {@code non-null;} file this instance is part of
     * @param out {@code non-null;} where to write to
     */
    public void writeTo(DexFile file, AnnotatedOutput out) {
        finishProcessingIfNecessary();

        if (out.annotates()) {
            annotateEntries("  ", null, out);
        }

        int tableSize = table.size();
        for (int i = 0; i < tableSize; i++) {
            CatchTable.Entry one = table.get(i);
            int start = one.getStart();
            int end = one.getEnd();
            int insnCount = end - start;

            if (insnCount >= 65536) {
                throw new UnsupportedOperationException(
                        "bogus exception range: " + Hex.u4(start) + ".." +
                        Hex.u4(end));
            }

            out.writeInt(start);
            out.writeShort(insnCount);
            out.writeShort(handlerOffsets.get(one.getHandlers()));
        }

        out.write(encodedHandlers);
    }

    /**
     * Helper method to annotate or simply print the exception handlers.
     * Only one of {@code printTo} or {@code annotateTo} should
     * be non-null.
     *
     * @param prefix {@code non-null;} prefix for each line
     * @param printTo {@code null-ok;} where to print to
     * @param annotateTo {@code null-ok;} where to consume bytes and annotate to
     */
    private void annotateEntries(String prefix, PrintWriter printTo,
            AnnotatedOutput annotateTo) {
        finishProcessingIfNecessary();

        boolean consume = (annotateTo != null);
        int amt1 = consume ? 6 : 0;
        int amt2 = consume ? 2 : 0;
        int size = table.size();
        String subPrefix = prefix + "  ";

        if (consume) {
            annotateTo.annotate(0, prefix + "tries:");
        } else {
            printTo.println(prefix + "tries:");
        }

        for (int i = 0; i < size; i++) {
            CatchTable.Entry entry = table.get(i);
            CatchHandlerList handlers = entry.getHandlers();
            String s1 = subPrefix + "try " + Hex.u2or4(entry.getStart())
                + ".." + Hex.u2or4(entry.getEnd());
            String s2 = handlers.toHuman(subPrefix, "");

            if (consume) {
                annotateTo.annotate(amt1, s1);
                annotateTo.annotate(amt2, s2);
            } else {
                printTo.println(s1);
                printTo.println(s2);
            }
        }

        if (! consume) {
            // Only emit the handler lists if we are consuming bytes.
            return;
        }

        annotateTo.annotate(0, prefix + "handlers:");
        annotateTo.annotate(encodedHandlerHeaderSize,
                subPrefix + "size: " + Hex.u2(handlerOffsets.size()));

        int lastOffset = 0;
        CatchHandlerList lastList = null;

        for (Map.Entry<CatchHandlerList, Integer> mapping :
                 handlerOffsets.entrySet()) {
            CatchHandlerList list = mapping.getKey();
            int offset = mapping.getValue();

            if (lastList != null) {
                annotateAndConsumeHandlers(lastList, lastOffset,
                        offset - lastOffset, subPrefix, printTo, annotateTo);
            }

            lastList = list;
            lastOffset = offset;
        }

        annotateAndConsumeHandlers(lastList, lastOffset,
                encodedHandlers.length - lastOffset,
                subPrefix, printTo, annotateTo);
    }

    /**
     * Helper for {@link #annotateEntries} to annotate a catch handler list
     * while consuming it.
     *
     * @param handlers {@code non-null;} handlers to annotate
     * @param offset {@code >= 0;} the offset of this handler
     * @param size {@code >= 1;} the number of bytes the handlers consume
     * @param prefix {@code non-null;} prefix for each line
     * @param printTo {@code null-ok;} where to print to
     * @param annotateTo {@code non-null;} where to annotate to
     */
    private static void annotateAndConsumeHandlers(CatchHandlerList handlers,
            int offset, int size, String prefix, PrintWriter printTo,
            AnnotatedOutput annotateTo) {
        String s = handlers.toHuman(prefix, Hex.u2(offset) + ": ");

        if (printTo != null) {
            printTo.println(s);
        }

        annotateTo.annotate(size, s);
    }
}
