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

import com.android.dexgen.rop.cst.CstType;
import com.android.dexgen.rop.type.StdTypeList;
import com.android.dexgen.rop.type.TypeList;
import com.android.dexgen.util.FixedSizeList;
import com.android.dexgen.util.IntList;

/**
 * List of catch entries, that is, the elements of an "exception table,"
 * which is part of a standard {@code Code} attribute.
 */
public final class ByteCatchList extends FixedSizeList {
    /** {@code non-null;} convenient zero-entry instance */
    public static final ByteCatchList EMPTY = new ByteCatchList(0);

    /**
     * Constructs an instance.
     *
     * @param count the number of elements to be in the table
     */
    public ByteCatchList(int count) {
        super(count);
    }

    /**
     * Gets the total length of this structure in bytes, when included in
     * a {@code Code} attribute. The returned value includes the
     * two bytes for {@code exception_table_length}.
     *
     * @return {@code >= 2;} the total length, in bytes
     */
    public int byteLength() {
        return 2 + size() * 8;
    }

    /**
     * Gets the indicated item.
     *
     * @param n {@code >= 0;} which item
     * @return {@code null-ok;} the indicated item
     */
    public Item get(int n) {
        return (Item) get0(n);
    }

    /**
     * Sets the item at the given index.
     *
     * @param n {@code >= 0, < size();} which entry to set
     * @param item {@code non-null;} the item
     */
    public void set(int n, Item item) {
        if (item == null) {
            throw new NullPointerException("item == null");
        }

        set0(n, item);
    }

    /**
     * Sets the item at the given index.
     *
     * @param n {@code >= 0, < size();} which entry to set
     * @param startPc {@code >= 0;} the start pc (inclusive) of the handler's range
     * @param endPc {@code >= startPc;} the end pc (exclusive) of the
     * handler's range
     * @param handlerPc {@code >= 0;} the pc of the exception handler
     * @param exceptionClass {@code null-ok;} the exception class or
     * {@code null} to catch all exceptions with this handler
     */
    public void set(int n, int startPc, int endPc, int handlerPc,
            CstType exceptionClass) {
        set0(n, new Item(startPc, endPc, handlerPc, exceptionClass));
    }

    /**
     * Gets the list of items active at the given address. The result is
     * automatically made immutable.
     *
     * @param pc which address
     * @return {@code non-null;} list of exception handlers active at
     * {@code pc}
     */
    public ByteCatchList listFor(int pc) {
        int sz = size();
        Item[] resultArr = new Item[sz];
        int resultSz = 0;

        for (int i = 0; i < sz; i++) {
            Item one = get(i);
            if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) {
                resultArr[resultSz] = one;
                resultSz++;
            }
        }

        if (resultSz == 0) {
            return EMPTY;
        }

        ByteCatchList result = new ByteCatchList(resultSz);
        for (int i = 0; i < resultSz; i++) {
            result.set(i, resultArr[i]);
        }

        result.setImmutable();
        return result;
    }

    /**
     * Helper method for {@link #listFor}, which tells whether a match
     * is <i>not</i> found for the exception type of the given item in
     * the given array. A match is considered to be either an exact type
     * match or the class {@code Object} which represents a catch-all.
     *
     * @param item {@code non-null;} item with the exception type to look for
     * @param arr {@code non-null;} array to search in
     * @param count {@code non-null;} maximum number of elements in the array to check
     * @return {@code true} iff the exception type is <i>not</i> found
     */
    private static boolean typeNotFound(Item item, Item[] arr, int count) {
        CstType type = item.getExceptionClass();

        for (int i = 0; i < count; i++) {
            CstType one = arr[i].getExceptionClass();
            if ((one == type) || (one == CstType.OBJECT)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Returns a target list corresponding to this instance. The result
     * is a list of all the exception handler addresses, with the given
     * {@code noException} address appended if appropriate. The
     * result is automatically made immutable.
     *
     * @param noException {@code >= -1;} the no-exception address to append, or
     * {@code -1} not to append anything
     * @return {@code non-null;} list of exception targets, with
     * {@code noException} appended if necessary
     */
    public IntList toTargetList(int noException) {
        if (noException < -1) {
            throw new IllegalArgumentException("noException < -1");
        }

        boolean hasDefault = (noException >= 0);
        int sz = size();

        if (sz == 0) {
            if (hasDefault) {
                /*
                 * The list is empty, but there is a no-exception
                 * address; so, the result is just that address.
                 */
                return IntList.makeImmutable(noException);
            }
            /*
             * The list is empty and there isn't even a no-exception
             * address.
             */
            return IntList.EMPTY;
        }

        IntList result = new IntList(sz + (hasDefault ? 1 : 0));

        for (int i = 0; i < sz; i++) {
            result.add(get(i).getHandlerPc());
        }

        if (hasDefault) {
            result.add(noException);
        }

        result.setImmutable();
        return result;
    }

    /**
     * Returns a rop-style catches list equivalent to this one.
     *
     * @return {@code non-null;} the converted instance
     */
    public TypeList toRopCatchList() {
        int sz = size();
        if (sz == 0) {
            return StdTypeList.EMPTY;
        }

        StdTypeList result = new StdTypeList(sz);

        for (int i = 0; i < sz; i++) {
            result.set(i, get(i).getExceptionClass().getClassType());
        }

        result.setImmutable();
        return result;
    }

    /**
     * Item in an exception handler list.
     */
    public static class Item {
        /** {@code >= 0;} the start pc (inclusive) of the handler's range */
        private final int startPc;

        /** {@code >= startPc;} the end pc (exclusive) of the handler's range */
        private final int endPc;

        /** {@code >= 0;} the pc of the exception handler */
        private final int handlerPc;

        /** {@code null-ok;} the exception class or {@code null} to catch all
         * exceptions with this handler */
        private final CstType exceptionClass;

        /**
         * Constructs an instance.
         *
         * @param startPc {@code >= 0;} the start pc (inclusive) of the
         * handler's range
         * @param endPc {@code >= startPc;} the end pc (exclusive) of the
         * handler's range
         * @param handlerPc {@code >= 0;} the pc of the exception handler
         * @param exceptionClass {@code null-ok;} the exception class or
         * {@code null} to catch all exceptions with this handler
         */
        public Item(int startPc, int endPc, int handlerPc,
                CstType exceptionClass) {
            if (startPc < 0) {
                throw new IllegalArgumentException("startPc < 0");
            }

            if (endPc < startPc) {
                throw new IllegalArgumentException("endPc < startPc");
            }

            if (handlerPc < 0) {
                throw new IllegalArgumentException("handlerPc < 0");
            }

            this.startPc = startPc;
            this.endPc = endPc;
            this.handlerPc = handlerPc;
            this.exceptionClass = exceptionClass;
        }

        /**
         * Gets the start pc (inclusive) of the handler's range.
         *
         * @return {@code >= 0;} the start pc (inclusive) of the handler's range.
         */
        public int getStartPc() {
            return startPc;
        }

        /**
         * Gets the end pc (exclusive) of the handler's range.
         *
         * @return {@code >= startPc;} the end pc (exclusive) of the
         * handler's range.
         */
        public int getEndPc() {
            return endPc;
        }

        /**
         * Gets the pc of the exception handler.
         *
         * @return {@code >= 0;} the pc of the exception handler
         */
        public int getHandlerPc() {
            return handlerPc;
        }

        /**
         * Gets the class of exception handled.
         *
         * @return {@code non-null;} the exception class; {@link CstType#OBJECT}
         * if this entry handles all possible exceptions
         */
        public CstType getExceptionClass() {
            return (exceptionClass != null) ?
                exceptionClass : CstType.OBJECT;
        }

        /**
         * Returns whether the given address is in the range of this item.
         *
         * @param pc the address
         * @return {@code true} iff this item covers {@code pc}
         */
        public boolean covers(int pc) {
            return (pc >= startPc) && (pc < endPc);
        }
    }
}
