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

import java.util.Arrays;

/**
 * Simple (mostly) fixed-size list of objects, which may be made immutable.
 */
public class FixedSizeList
        extends MutabilityControl implements ToHuman {
    /** {@code non-null;} array of elements */
    private Object[] arr;

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

        try {
            arr = new Object[size];
        } catch (NegativeArraySizeException ex) {
            // Translate the exception.
            throw new IllegalArgumentException("size < 0");
        }
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object other) {
        if (this == other) {
            // Easy out.
            return true;
        }

        if ((other == null) || (getClass() != other.getClass())) {
            // Another easy out.
            return false;
        }

        FixedSizeList list = (FixedSizeList) other;
        return Arrays.equals(arr, list.arr);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return Arrays.hashCode(arr);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        String name = getClass().getName();

        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
                         ", ",
                         "}",
                         false);
    }

    /**
     * {@inheritDoc}
     *
     * This method will only work if every element of the list
     * implements {@link ToHuman}.
     */
    public String toHuman() {
        String name = getClass().getName();

        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
                         ", ",
                         "}",
                         true);
    }

    /**
     * Gets a customized string form for this instance.
     *
     * @param prefix {@code null-ok;} prefix for the start of the result
     * @param separator {@code null-ok;} separator to insert between each item
     * @param suffix {@code null-ok;} suffix for the end of the result
     * @return {@code non-null;} the custom string
     */
    public String toString(String prefix, String separator, String suffix) {
        return toString0(prefix, separator, suffix, false);
    }

    /**
     * Gets a customized human string for this instance. This method will
     * only work if every element of the list implements {@link
     * ToHuman}.
     *
     * @param prefix {@code null-ok;} prefix for the start of the result
     * @param separator {@code null-ok;} separator to insert between each item
     * @param suffix {@code null-ok;} suffix for the end of the result
     * @return {@code non-null;} the custom string
     */
    public String toHuman(String prefix, String separator, String suffix) {
        return toString0(prefix, separator, suffix, true);
    }

    /**
     * Gets the number of elements in this list.
     */
    public final int size() {
        return arr.length;
    }

    /**
     * Shrinks this instance to fit, by removing any unset
     * ({@code null}) elements, leaving the remaining elements in
     * their original order.
     */
    public void shrinkToFit() {
        int sz = arr.length;
        int newSz = 0;

        for (int i = 0; i < sz; i++) {
            if (arr[i] != null) {
                newSz++;
            }
        }

        if (sz == newSz) {
            return;
        }

        throwIfImmutable();

        Object[] newa = new Object[newSz];
        int at = 0;

        for (int i = 0; i < sz; i++) {
            Object one = arr[i];
            if (one != null) {
                newa[at] = one;
                at++;
            }
        }

        arr = newa;
        if (newSz == 0) {
            setImmutable();
        }
    }

    /**
     * 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}. This method is
     * protected so that subclasses may offer a safe type-checked
     * public interface to their clients.
     *
     * @param n {@code >= 0, < size();} which element
     * @return {@code non-null;} the indicated element
     */
    protected final Object get0(int n) {
        try {
            Object result = arr[n];

            if (result == null) {
                throw new NullPointerException("unset: " + n);
            }

            return result;
        } catch (ArrayIndexOutOfBoundsException ex) {
            // Translate the exception.
            return throwIndex(n);
        }
    }

    /**
     * Gets the indicated element, allowing {@code null}s to be
     * returned. This method is protected so that subclasses may
     * (optionally) offer a safe type-checked public interface to
     * their clients.
     *
     * @param n {@code >= 0, < size();} which element
     * @return {@code null-ok;} the indicated element
     */
    protected final Object getOrNull0(int n) {
        return arr[n];
    }

    /**
     * Sets the element at the given index, but without doing any type
     * checks on the element. This method is protected so that
     * subclasses may offer a safe type-checked public interface to
     * their clients.
     *
     * @param n {@code >= 0, < size();} which element
     * @param obj {@code null-ok;} the value to store
     */
    protected final void set0(int n, Object obj) {
        throwIfImmutable();

        try {
            arr[n] = obj;
        } catch (ArrayIndexOutOfBoundsException ex) {
            // Translate the exception.
            throwIndex(n);
        }
    }

    /**
     * Throws the appropriate exception for the given index value.
     *
     * @param n the index value
     * @return never
     * @throws IndexOutOfBoundsException always thrown
     */
    private Object throwIndex(int n) {
        if (n < 0) {
            throw new IndexOutOfBoundsException("n < 0");
        }

        throw new IndexOutOfBoundsException("n >= size()");
    }

    /**
     * Helper for {@link #toString} and {@link #toHuman}, which both of
     * those call to pretty much do everything.
     *
     * @param prefix {@code null-ok;} prefix for the start of the result
     * @param separator {@code null-ok;} separator to insert between each item
     * @param suffix {@code null-ok;} suffix for the end of the result
     * @param human whether the output is to be human
     * @return {@code non-null;} the custom string
     */
    private String toString0(String prefix, String separator, String suffix,
                             boolean human) {
        int len = arr.length;
        StringBuffer sb = new StringBuffer(len * 10 + 10);

        if (prefix != null) {
            sb.append(prefix);
        }

        for (int i = 0; i < len; i++) {
            if ((i != 0) && (separator != null)) {
                sb.append(separator);
            }

            if (human) {
                sb.append(((ToHuman) arr[i]).toHuman());
            } else {
                sb.append(arr[i]);
            }
        }

        if (suffix != null) {
            sb.append(suffix);
        }

        return sb.toString();
    }

}
