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

import com.android.dx.util.FixedSizeList;

/**
 * Standard implementation of {@link TypeList}.
 */
public final class StdTypeList
        extends FixedSizeList implements TypeList {
    /** {@code non-null;} no-element instance */
    public static final StdTypeList EMPTY = new StdTypeList(0);

    /** {@code non-null;} the list {@code [int]} */
    public static final StdTypeList INT = StdTypeList.make(Type.INT);

    /** {@code non-null;} the list {@code [long]} */
    public static final StdTypeList LONG = StdTypeList.make(Type.LONG);

    /** {@code non-null;} the list {@code [float]} */
    public static final StdTypeList FLOAT = StdTypeList.make(Type.FLOAT);

    /** {@code non-null;} the list {@code [double]} */
    public static final StdTypeList DOUBLE = StdTypeList.make(Type.DOUBLE);

    /** {@code non-null;} the list {@code [Object]} */
    public static final StdTypeList OBJECT = StdTypeList.make(Type.OBJECT);

    /** {@code non-null;} the list {@code [ReturnAddress]} */
    public static final StdTypeList RETURN_ADDRESS
            = StdTypeList.make(Type.RETURN_ADDRESS);

    /** {@code non-null;} the list {@code [Throwable]} */
    public static final StdTypeList THROWABLE =
        StdTypeList.make(Type.THROWABLE);

    /** {@code non-null;} the list {@code [int, int]} */
    public static final StdTypeList INT_INT =
        StdTypeList.make(Type.INT, Type.INT);

    /** {@code non-null;} the list {@code [long, long]} */
    public static final StdTypeList LONG_LONG =
        StdTypeList.make(Type.LONG, Type.LONG);

    /** {@code non-null;} the list {@code [float, float]} */
    public static final StdTypeList FLOAT_FLOAT =
        StdTypeList.make(Type.FLOAT, Type.FLOAT);

    /** {@code non-null;} the list {@code [double, double]} */
    public static final StdTypeList DOUBLE_DOUBLE =
        StdTypeList.make(Type.DOUBLE, Type.DOUBLE);

    /** {@code non-null;} the list {@code [Object, Object]} */
    public static final StdTypeList OBJECT_OBJECT =
        StdTypeList.make(Type.OBJECT, Type.OBJECT);

    /** {@code non-null;} the list {@code [int, Object]} */
    public static final StdTypeList INT_OBJECT =
        StdTypeList.make(Type.INT, Type.OBJECT);

    /** {@code non-null;} the list {@code [long, Object]} */
    public static final StdTypeList LONG_OBJECT =
        StdTypeList.make(Type.LONG, Type.OBJECT);

    /** {@code non-null;} the list {@code [float, Object]} */
    public static final StdTypeList FLOAT_OBJECT =
        StdTypeList.make(Type.FLOAT, Type.OBJECT);

    /** {@code non-null;} the list {@code [double, Object]} */
    public static final StdTypeList DOUBLE_OBJECT =
        StdTypeList.make(Type.DOUBLE, Type.OBJECT);

    /** {@code non-null;} the list {@code [long, int]} */
    public static final StdTypeList LONG_INT =
        StdTypeList.make(Type.LONG, Type.INT);

    /** {@code non-null;} the list {@code [int[], int]} */
    public static final StdTypeList INTARR_INT =
        StdTypeList.make(Type.INT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [long[], int]} */
    public static final StdTypeList LONGARR_INT =
        StdTypeList.make(Type.LONG_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [float[], int]} */
    public static final StdTypeList FLOATARR_INT =
        StdTypeList.make(Type.FLOAT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [double[], int]} */
    public static final StdTypeList DOUBLEARR_INT =
        StdTypeList.make(Type.DOUBLE_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [Object[], int]} */
    public static final StdTypeList OBJECTARR_INT =
        StdTypeList.make(Type.OBJECT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [boolean[], int]} */
    public static final StdTypeList BOOLEANARR_INT =
        StdTypeList.make(Type.BOOLEAN_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [byte[], int]} */
    public static final StdTypeList BYTEARR_INT =
        StdTypeList.make(Type.BYTE_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [char[], int]} */
    public static final StdTypeList CHARARR_INT =
        StdTypeList.make(Type.CHAR_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [short[], int]} */
    public static final StdTypeList SHORTARR_INT =
        StdTypeList.make(Type.SHORT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [int, int[], int]} */
    public static final StdTypeList INT_INTARR_INT =
        StdTypeList.make(Type.INT, Type.INT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [long, long[], int]} */
    public static final StdTypeList LONG_LONGARR_INT =
        StdTypeList.make(Type.LONG, Type.LONG_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [float, float[], int]} */
    public static final StdTypeList FLOAT_FLOATARR_INT =
        StdTypeList.make(Type.FLOAT, Type.FLOAT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [double, double[], int]} */
    public static final StdTypeList DOUBLE_DOUBLEARR_INT =
        StdTypeList.make(Type.DOUBLE, Type.DOUBLE_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [Object, Object[], int]} */
    public static final StdTypeList OBJECT_OBJECTARR_INT =
        StdTypeList.make(Type.OBJECT, Type.OBJECT_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [int, boolean[], int]} */
    public static final StdTypeList INT_BOOLEANARR_INT =
        StdTypeList.make(Type.INT, Type.BOOLEAN_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [int, byte[], int]} */
    public static final StdTypeList INT_BYTEARR_INT =
        StdTypeList.make(Type.INT, Type.BYTE_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [int, char[], int]} */
    public static final StdTypeList INT_CHARARR_INT =
        StdTypeList.make(Type.INT, Type.CHAR_ARRAY, Type.INT);

    /** {@code non-null;} the list {@code [int, short[], int]} */
    public static final StdTypeList INT_SHORTARR_INT =
        StdTypeList.make(Type.INT, Type.SHORT_ARRAY, Type.INT);

    /**
     * Makes a single-element instance.
     *
     * @param type {@code non-null;} the element
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static StdTypeList make(Type type) {
        StdTypeList result = new StdTypeList(1);
        result.set(0, type);
        return result;
    }

    /**
     * Makes a two-element instance.
     *
     * @param type0 {@code non-null;} the first element
     * @param type1 {@code non-null;} the second element
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static StdTypeList make(Type type0, Type type1) {
        StdTypeList result = new StdTypeList(2);
        result.set(0, type0);
        result.set(1, type1);
        return result;
    }

    /**
     * Makes a three-element instance.
     *
     * @param type0 {@code non-null;} the first element
     * @param type1 {@code non-null;} the second element
     * @param type2 {@code non-null;} the third element
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static StdTypeList make(Type type0, Type type1, Type type2) {
        StdTypeList result = new StdTypeList(3);
        result.set(0, type0);
        result.set(1, type1);
        result.set(2, type2);
        return result;
    }

    /**
     * Makes a four-element instance.
     *
     * @param type0 {@code non-null;} the first element
     * @param type1 {@code non-null;} the second element
     * @param type2 {@code non-null;} the third element
     * @param type3 {@code non-null;} the fourth element
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static StdTypeList make(Type type0, Type type1, Type type2,
                                   Type type3) {
        StdTypeList result = new StdTypeList(4);
        result.set(0, type0);
        result.set(1, type1);
        result.set(2, type2);
        result.set(3, type3);
        return result;
    }

    /**
     * Returns the given list as a comma-separated list of human forms. This
     * is a static method so as to work on arbitrary {@link TypeList}
     * instances.
     *
     * @param list {@code non-null;} the list to convert
     * @return {@code non-null;} the human form
     */
    public static String toHuman(TypeList list) {
        int size = list.size();

        if (size == 0) {
            return "<empty>";
        }

        StringBuffer sb = new StringBuffer(100);

        for (int i = 0; i < size; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(list.getType(i).toHuman());
        }

        return sb.toString();
    }

    /**
     * Returns a hashcode of the contents of the given list. This
     * is a static method so as to work on arbitrary {@link TypeList}
     * instances.
     *
     * @param list {@code non-null;} the list to inspect
     * @return {@code non-null;} the hash code
     */
    public static int hashContents(TypeList list) {
        int size = list.size();
        int hash = 0;

        for (int i = 0; i < size; i++) {
            hash = (hash * 31) + list.getType(i).hashCode();
        }

        return hash;
    }

    /**
     * Compares the contents of the given two instances for equality. This
     * is a static method so as to work on arbitrary {@link TypeList}
     * instances.
     *
     * @param list1 {@code non-null;} one list to compare
     * @param list2 {@code non-null;} another list to compare
     * @return whether the two lists contain corresponding equal elements
     */
    public static boolean equalContents(TypeList list1, TypeList list2) {
        int size = list1.size();

        if (list2.size() != size) {
            return false;
        }

        for (int i = 0; i < size; i++) {
            if (! list1.getType(i).equals(list2.getType(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * Compares the contents of the given two instances for ordering. This
     * is a static method so as to work on arbitrary {@link TypeList}
     * instances.
     *
     * @param list1 {@code non-null;} one list to compare
     * @param list2 {@code non-null;} another list to compare
     * @return the order of the two lists
     */
    public static int compareContents(TypeList list1, TypeList list2) {
        int size1 = list1.size();
        int size2 = list2.size();
        int size = Math.min(size1, size2);

        for (int i = 0; i < size; i++) {
            int comparison = list1.getType(i).compareTo(list2.getType(i));
            if (comparison != 0) {
                return comparison;
            }
        }

        if (size1 == size2) {
            return 0;
        } else if (size1 < size2) {
            return -1;
        } else {
            return 1;
        }
    }

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

    /** {@inheritDoc} */
    public Type getType(int n) {
        return get(n);
    }

    /** {@inheritDoc} */
    public int getWordCount() {
        int sz = size();
        int result = 0;

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

        return result;
    }

    /** {@inheritDoc} */
    public TypeList withAddedType(Type type) {
        int sz = size();
        StdTypeList result = new StdTypeList(sz + 1);

        for (int i = 0; i < sz; i++) {
            result.set0(i, get0(i));
        }

        result.set(sz, type);
        result.setImmutable();
        return result;
    }

    /**
     * Gets the indicated element. 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 element
     * @return {@code non-null;} the indicated element
     */
    public Type get(int n) {
        return (Type) get0(n);
    }

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

    /**
     * Returns a new instance, which is the same as this instance,
     * except that it has an additional type prepended to the
     * original.
     *
     * @param type {@code non-null;} the new first element
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public StdTypeList withFirst(Type type) {
        int sz = size();
        StdTypeList result = new StdTypeList(sz + 1);

        result.set0(0, type);
        for (int i = 0; i < sz; i++) {
            result.set0(i + 1, getOrNull0(i));
        }

        return result;
    }
}
