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

import com.android.dx.rop.cst.CstType;
import com.android.dx.util.FixedSizeList;
import com.android.dx.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;
        }
    }
}
