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

import com.android.dx.util.IntList;
import com.android.dx.util.MutabilityControl;

/**
 * List of (value, target) mappings representing the choices of a
 * {@code tableswitch} or {@code lookupswitch} instruction. It
 * also holds the default target for the switch.
 */
public final class SwitchList extends MutabilityControl {
    /** {@code non-null;} list of test values */
    private final IntList values;

    /**
     * {@code non-null;} list of targets corresponding to the test values; there
     * is always one extra element in the target list, to hold the
     * default target 
     */
    private final IntList targets;

    /** ultimate size of the list */
    private int size;

    /**
     * Constructs an instance.
     * 
     * @param size {@code >= 0;} the number of elements to be in the table
     */
    public SwitchList(int size) {
        super(true);
        this.values = new IntList(size);
        this.targets = new IntList(size + 1);
        this.size = size;
    }

    /** {@inheritDoc} */
    @Override
    public void setImmutable() {
        values.setImmutable();
        targets.setImmutable();
        super.setImmutable();
    }

    /**
     * Gets the size of the list.
     * 
     * @return {@code >= 0;} the list size
     */
    public int size() {
        return size;
    }

    /**
     * Gets the indicated test value.
     * 
     * @param n {@code >= 0;}, &lt; size(); which index
     * @return the test value 
     */
    public int getValue(int n) {
        return values.get(n);
    }

    /**
     * Gets the indicated target. Asking for the target at {@code size()}
     * returns the default target.
     * 
     * @param n {@code >= 0, <= size();} which index
     * @return {@code >= 0;} the target
     */
    public int getTarget(int n) {
        return targets.get(n);
    }

    /**
     * Gets the default target. This is just a shorthand for
     * {@code getTarget(size())}.
     * 
     * @return {@code >= 0;} the default target
     */
    public int getDefaultTarget() {
        return targets.get(size);
    }

    /**
     * Gets the list of all targets. This includes one extra element at the
     * end of the list, which holds the default target.
     * 
     * @return {@code non-null;} the target list
     */
    public IntList getTargets() {
        return targets;
    }

    /**
     * Gets the list of all case values.
     * 
     * @return {@code non-null;} the case value list
     */
    public IntList getValues() {
        return values;
    }

    /**
     * Sets the default target. It is only valid to call this method
     * when all the non-default elements have been set.
     * 
     * @param target {@code >= 0;} the absolute (not relative) default target
     * address
     */
    public void setDefaultTarget(int target) {
        throwIfImmutable();

        if (target < 0) {
            throw new IllegalArgumentException("target < 0");
        }

        if (targets.size() != size) {
            throw new RuntimeException("non-default elements not all set");
        }

        targets.add(target);
    }

    /**
     * Adds the given item.
     * 
     * @param value the test value
     * @param target {@code >= 0;} the absolute (not relative) target address
     */
    public void add(int value, int target) {
        throwIfImmutable();

        if (target < 0) {
            throw new IllegalArgumentException("target < 0");
        }

        values.add(value);
        targets.add(target);
    }

    /**
     * Shrinks this instance if possible, removing test elements that
     * refer to the default target. This is only valid after the instance
     * is fully populated, including the default target (naturally).
     */
    public void removeSuperfluousDefaults() {
        throwIfImmutable();

        int sz = size;

        if (sz != (targets.size() - 1)) {
            throw new IllegalArgumentException("incomplete instance");
        }

        int defaultTarget = targets.get(sz);
        int at = 0;

        for (int i = 0; i < sz; i++) {
            int target = targets.get(i);
            if (target != defaultTarget) {
                if (i != at) {
                    targets.set(at, target);
                    values.set(at, values.get(i));
                }
                at++;
            }
        }

        if (at != sz) {
            values.shrink(at);
            targets.set(at, defaultTarget);
            targets.shrink(at + 1);
            size = at;
        }
    }
}
