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

import com.android.dexgen.rop.cst.CstType;
import com.android.dexgen.util.FixedSizeList;
import com.android.dexgen.util.Hex;

/**
 * Ordered list of (exception type, handler address) entries.
 */
public final class CatchHandlerList extends FixedSizeList
        implements Comparable<CatchHandlerList> {
    /** {@code non-null;} empty instance */
    public static final CatchHandlerList EMPTY = new CatchHandlerList(0);

    /**
     * Constructs an instance. All indices initially contain {@code null}.
     *
     * @param size {@code >= 0;} the size of the list
     */
    public CatchHandlerList(int size) {
        super(size);
    }

    /**
     * Gets the element at the given index. It is an error to call
     * this with the index for an element which was never set; if you
     * do that, this will throw {@code NullPointerException}.
     *
     * @param n {@code >= 0, < size();} which index
     * @return {@code non-null;} element at that index
     */
    public Entry get(int n) {
        return (Entry) get0(n);
    }

    /** {@inheritDoc} */
    public String toHuman() {
        return toHuman("", "");
    }

    /**
     * Get the human form of this instance, prefixed on each line
     * with the string.
     *
     * @param prefix {@code non-null;} the prefix for every line
     * @param header {@code non-null;} the header for the first line (after the
     * first prefix)
     * @return {@code non-null;} the human form
     */
    public String toHuman(String prefix, String header) {
        StringBuilder sb = new StringBuilder(100);
        int size = size();

        sb.append(prefix);
        sb.append(header);
        sb.append("catch ");

        for (int i = 0; i < size; i++) {
            Entry entry = get(i);

            if (i != 0) {
                sb.append(",\n");
                sb.append(prefix);
                sb.append("  ");
            }

            if ((i == (size - 1)) && catchesAll()) {
                sb.append("<any>");
            } else {
                sb.append(entry.getExceptionType().toHuman());
            }

            sb.append(" -> ");
            sb.append(Hex.u2or4(entry.getHandler()));
        }

        return sb.toString();
    }

    /**
     * Returns whether or not this instance ends with a "catch-all"
     * handler.
     *
     * @return {@code true} if this instance ends with a "catch-all"
     * handler or {@code false} if not
     */
    public boolean catchesAll() {
        int size = size();

        if (size == 0) {
            return false;
        }

        Entry last = get(size - 1);
        return last.getExceptionType().equals(CstType.OBJECT);
    }

    /**
     * Sets the entry at the given index.
     *
     * @param n {@code >= 0, < size();} which index
     * @param exceptionType {@code non-null;} type of exception handled
     * @param handler {@code >= 0;} exception handler address
     */
    public void set(int n, CstType exceptionType, int handler) {
        set0(n, new Entry(exceptionType, handler));
    }

    /**
     * Sets the entry at the given index.
     *
     * @param n {@code >= 0, < size();} which index
     * @param entry {@code non-null;} the entry to set at {@code n}
     */
    public void set(int n, Entry entry) {
        set0(n, entry);
    }

    /** {@inheritDoc} */
    public int compareTo(CatchHandlerList other) {
        if (this == other) {
            // Easy out.
            return 0;
        }

        int thisSize = size();
        int otherSize = other.size();
        int checkSize = Math.min(thisSize, otherSize);

        for (int i = 0; i < checkSize; i++) {
            Entry thisEntry = get(i);
            Entry otherEntry = other.get(i);
            int compare = thisEntry.compareTo(otherEntry);
            if (compare != 0) {
                return compare;
            }
        }

        if (thisSize < otherSize) {
            return -1;
        } else if (thisSize > otherSize) {
            return 1;
        }

        return 0;
    }

    /**
     * Entry in the list.
     */
    public static class Entry implements Comparable<Entry> {
        /** {@code non-null;} type of exception handled */
        private final CstType exceptionType;

        /** {@code >= 0;} exception handler address */
        private final int handler;

        /**
         * Constructs an instance.
         *
         * @param exceptionType {@code non-null;} type of exception handled
         * @param handler {@code >= 0;} exception handler address
         */
        public Entry(CstType exceptionType, int handler) {
            if (handler < 0) {
                throw new IllegalArgumentException("handler < 0");
            }

            if (exceptionType == null) {
                throw new NullPointerException("exceptionType == null");
            }

            this.handler = handler;
            this.exceptionType = exceptionType;
        }

        /** {@inheritDoc} */
        @Override
        public int hashCode() {
            return (handler * 31) + exceptionType.hashCode();
        }

        /** {@inheritDoc} */
        @Override
        public boolean equals(Object other) {
            if (other instanceof Entry) {
                return (compareTo((Entry) other) == 0);
            }

            return false;
        }

        /** {@inheritDoc} */
        public int compareTo(Entry other) {
            if (handler < other.handler) {
                return -1;
            } else if (handler > other.handler) {
                return 1;
            }

            return exceptionType.compareTo(other.exceptionType);
        }

        /**
         * Gets the exception type handled.
         *
         * @return {@code non-null;} the exception type
         */
        public CstType getExceptionType() {
            return exceptionType;
        }

        /**
         * Gets the handler address.
         *
         * @return {@code >= 0;} the handler address
         */
        public int getHandler() {
            return handler;
        }
    }
}
