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

import java.util.Arrays;

/**
 * A list of labeled items, allowing easy lookup by label.
 */
public class LabeledList extends FixedSizeList {
    /**
     * Sparse array indexed by label to FixedSizeList index;
     * {@code -1} for an invalid label.
     */
    private final IntList labelToIndex;

    /** @inheritDoc */
    public LabeledList(int size) {
        super(size);

        labelToIndex = new IntList(size);
    }

    /**
     * Constructs a new instance that is a copy of the old instance.
     *
     * @param old instance to copy
     */
    public LabeledList(LabeledList old) {
        super(old.size());
        labelToIndex = old.labelToIndex.mutableCopy();

        int sz = old.size();

        for (int i = 0; i < sz; i++) {
            Object one = old.get0(i);
            if (one != null) {
                set0(i, one);
            }
        }
    }

    /**
     * Gets the maximum label (exclusive) of any block added to this instance.
     *
     * @return {@code >= 0;} the maximum label
     */
    public final int getMaxLabel() {
        int sz = labelToIndex.size();

        // Gobble any deleted labels that may be at the end.
        int i;
        for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--)
            /*empty*/ ;

        int newSize = i + 1;

        labelToIndex.shrink(newSize);

        return newSize;
    }

    /**
     * Removes a label from the label-to-index mapping.
     *
     * @param oldLabel label to remove
     */
    private void removeLabel(int oldLabel) {
        labelToIndex.set(oldLabel, -1);
    }

    /**
     * Adds a label and index to the label-to-index mapping.
     *
     * @param label new label
     * @param index index of block.
     */
    private void addLabelIndex(int label, int index) {
        int origSz = labelToIndex.size();

        for (int i = 0; i <= (label - origSz); i++) {
            labelToIndex.add(-1);
        }

        labelToIndex.set(label, index);
    }

    /**
     * Gets the index of the first item in the list with the given
     * label, if any.
     *
     * @param label {@code >= 0;} the label to look for
     * @return {@code >= -1;} the index of the so-labelled item, or {@code -1}
     * if none is found
     */
    public final int indexOfLabel(int label) {
        if (label >= labelToIndex.size()) {
            return -1;
        } else {
            return labelToIndex.get(label);
        }
    }

    /**
     * Gets an array containing all of the labels used in this instance,
     * in order. The returned array is freshly-allocated and so may be
     * modified safely by the caller without impacting this instance.
     *
     * @return {@code non-null;} ordered array of labels
     * @throws NullPointerException thrown if there are any {@code null}
     * items in this instance
     */
    public final int[] getLabelsInOrder() {
        int sz = size();
        int[] result = new int[sz];

        for (int i = 0; i < sz; i++) {
            LabeledItem li = (LabeledItem) get0(i);
            if (li == null) {
                throw new NullPointerException("null at index " + i);
            }
            result[i] = li.getLabel();
        }

        Arrays.sort(result);
        return result;
    }

    /** @inheritDoc */
    @Override
    public void shrinkToFit() {
        super.shrinkToFit();

        rebuildLabelToIndex();
    }

    /**
     * Rebuilds the label-to-index mapping after a {@code shrinkToFit()}.
     * Note: This assumes that the labels that are in the list are the
     * same, although the indicies may have changed.
     */
    private void rebuildLabelToIndex() {
        int szItems = size();

        for (int i = 0; i < szItems; i++) {
            LabeledItem li = (LabeledItem) get0(i);

            if (li != null) {
                labelToIndex.set(li.getLabel(), i);
            }
        }
    }

    /**
     * Sets the element at the given index.
     *
     * @param n {@code >= 0, < size();} which element
     * @param item {@code null-ok;} the value to store
     */
    protected void set(int n, LabeledItem item) {
        LabeledItem old = (LabeledItem) getOrNull0(n);

        set0(n, item);

        if (old != null) {
            removeLabel(old.getLabel());
        }

        if (item != null) {
            addLabelIndex(item.getLabel(), n);
        }
    }
}
