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

import com.android.dx.util.MutabilityControl;

/**
 * Set of {@link RegisterSpec} instances, where a given register number
 * may appear only once in the set.
 */
public final class RegisterSpecSet
        extends MutabilityControl {
    /** {@code non-null;} no-element instance */
    public static final RegisterSpecSet EMPTY = new RegisterSpecSet(0);

    /**
     * {@code non-null;} array of register specs, where each element is
     * {@code null} or is an instance whose {@code reg}
     * matches the array index
     */
    private final RegisterSpec[] specs;

    /** {@code >= -1;} size of the set or {@code -1} if not yet calculated */
    private int size;

    /**
     * Constructs an instance. The instance is initially empty.
     *
     * @param maxSize {@code >= 0;} the maximum register number (exclusive) that
     * may be represented in this instance
     */
    public RegisterSpecSet(int maxSize) {
        super(maxSize != 0);

        this.specs = new RegisterSpec[maxSize];
        this.size = 0;
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object other) {
        if (!(other instanceof RegisterSpecSet)) {
            return false;
        }

        RegisterSpecSet otherSet = (RegisterSpecSet) other;
        RegisterSpec[] otherSpecs = otherSet.specs;
        int len = specs.length;

        if ((len != otherSpecs.length) || (size() != otherSet.size())) {
            return false;
        }

        for (int i = 0; i < len; i++) {
            RegisterSpec s1 = specs[i];
            RegisterSpec s2 = otherSpecs[i];

            if (s1 == s2) {
                continue;
            }

            if ((s1 == null) || !s1.equals(s2)) {
                return false;
            }
        }

        return true;
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        int len = specs.length;
        int hash = 0;

        for (int i = 0; i < len; i++) {
            RegisterSpec spec = specs[i];
            int oneHash = (spec == null) ? 0 : spec.hashCode();
            hash = (hash * 31) + oneHash;
        }

        return hash;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        int len = specs.length;
        StringBuffer sb = new StringBuffer(len * 25);

        sb.append('{');

        boolean any = false;
        for (int i = 0; i < len; i++) {
            RegisterSpec spec = specs[i];
            if (spec != null) {
                if (any) {
                    sb.append(", ");
                } else {
                    any = true;
                }
                sb.append(spec);
            }
        }

        sb.append('}');
        return sb.toString();
    }

    /**
     * Gets the maximum number of registers that may be in this instance, which
     * is also the maximum-plus-one of register numbers that may be
     * represented.
     *
     * @return {@code >= 0;} the maximum size
     */
    public int getMaxSize() {
        return specs.length;
    }

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

        if (result < 0) {
            int len = specs.length;

            result = 0;
            for (int i = 0; i < len; i++) {
                if (specs[i] != null) {
                    result++;
                }
            }

            size = result;
        }

        return result;
    }

    /**
     * Gets the element with the given register number, if any.
     *
     * @param reg {@code >= 0;} the desired register number
     * @return {@code null-ok;} the element with the given register number or
     * {@code null} if there is none
     */
    public RegisterSpec get(int reg) {
        try {
            return specs[reg];
        } catch (ArrayIndexOutOfBoundsException ex) {
            // Translate the exception.
            throw new IllegalArgumentException("bogus reg");
        }
    }

    /**
     * Gets the element with the same register number as the given
     * spec, if any. This is just a convenient shorthand for
     * {@code get(spec.getReg())}.
     *
     * @param spec {@code non-null;} spec with the desired register number
     * @return {@code null-ok;} the element with the matching register number or
     * {@code null} if there is none
     */
    public RegisterSpec get(RegisterSpec spec) {
        return get(spec.getReg());
    }

    /**
     * Returns the spec in this set that's currently associated with a
     * given local (type, name, and signature), or {@code null} if there is
     * none. This ignores the register number of the given spec but
     * matches on everything else.
     *
     * @param spec {@code non-null;} local to look for
     * @return {@code null-ok;} first register found that matches, if any
     */
    public RegisterSpec findMatchingLocal(RegisterSpec spec) {
        int length = specs.length;

        for (int reg = 0; reg < length; reg++) {
            RegisterSpec s = specs[reg];

            if (s == null) {
                continue;
            }

            if (spec.matchesVariable(s)) {
                return s;
            }
        }

        return null;
    }

    /**
     * Returns the spec in this set that's currently associated with a given
     * local (name and signature), or {@code null} if there is none.
     *
     * @param local {@code non-null;} local item to search for
     * @return {@code null-ok;} first register found with matching name and signature
     */
    public RegisterSpec localItemToSpec(LocalItem local) {
        int length = specs.length;

        for (int reg = 0; reg < length; reg++) {
            RegisterSpec spec = specs[reg];

            if ((spec != null) && local.equals(spec.getLocalItem())) {
                return spec;
            }
        }

        return null;
    }

    /**
     * Removes a spec from the set. Only the register number
     * of the parameter is significant.
     *
     * @param toRemove {@code non-null;} register to remove.
     */
    public void remove(RegisterSpec toRemove) {
        try {
            specs[toRemove.getReg()] = null;
            size = -1;
        } catch (ArrayIndexOutOfBoundsException ex) {
            // Translate the exception.
            throw new IllegalArgumentException("bogus reg");
        }
    }

    /**
     * Puts the given spec into the set. If there is already an element in
     * the set with the same register number, it is replaced. Additionally,
     * if the previous element is for a category-2 register, then that
     * previous element is nullified. Finally, if the given spec is for
     * a category-2 register, then the immediately subsequent element
     * is nullified.
     *
     * @param spec {@code non-null;} the register spec to put in the instance
     */
    public void put(RegisterSpec spec) {
        throwIfImmutable();

        if (spec == null) {
            throw new NullPointerException("spec == null");
        }

        size = -1;

        try {
            int reg = spec.getReg();
            specs[reg] = spec;

            if (reg > 0) {
                int prevReg = reg - 1;
                RegisterSpec prevSpec = specs[prevReg];
                if ((prevSpec != null) && (prevSpec.getCategory() == 2)) {
                    specs[prevReg] = null;
                }
            }

            if (spec.getCategory() == 2) {
                specs[reg + 1] = null;
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            // Translate the exception.
            throw new IllegalArgumentException("spec.getReg() out of range");
        }
    }

    /**
     * Put the entire contents of the given set into this one.
     *
     * @param set {@code non-null;} the set to put into this instance
     */
    public void putAll(RegisterSpecSet set) {
        int max = set.getMaxSize();

        for (int i = 0; i < max; i++) {
            RegisterSpec spec = set.get(i);
            if (spec != null) {
                put(spec);
            }
        }
    }

    /**
     * Intersects this instance with the given one, modifying this
     * instance. The intersection consists of the pairwise
     * {@link RegisterSpec#intersect} of corresponding elements from
     * this instance and the given one where both are non-null.
     *
     * @param other {@code non-null;} set to intersect with
     * @param localPrimary whether local variables are primary to
     * the intersection; if {@code true}, then the only non-null
     * result elements occur when registers being intersected have
     * equal names (or both have {@code null} names)
     */
    public void intersect(RegisterSpecSet other, boolean localPrimary) {
        throwIfImmutable();

        RegisterSpec[] otherSpecs = other.specs;
        int thisLen = specs.length;
        int len = Math.min(thisLen, otherSpecs.length);

        size = -1;

        for (int i = 0; i < len; i++) {
            RegisterSpec spec = specs[i];

            if (spec == null) {
                continue;
            }

            RegisterSpec intersection =
                spec.intersect(otherSpecs[i], localPrimary);
            if (intersection != spec) {
                specs[i] = intersection;
            }
        }

        for (int i = len; i < thisLen; i++) {
            specs[i] = null;
        }
    }

    /**
     * Returns an instance that is identical to this one, except that
     * all register numbers are offset by the given amount. Mutability
     * of the result is inherited from the original.
     *
     * @param delta the amount to offset the register numbers by
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public RegisterSpecSet withOffset(int delta) {
        int len = specs.length;
        RegisterSpecSet result = new RegisterSpecSet(len + delta);

        for (int i = 0; i < len; i++) {
            RegisterSpec spec = specs[i];
            if (spec != null) {
                result.put(spec.withOffset(delta));
            }
        }

        result.size = size;

        if (isImmutable()) {
            result.setImmutable();
        }

        return result;
    }

    /**
     * Makes and return a mutable copy of this instance.
     *
     * @return {@code non-null;} the mutable copy
     */
    public RegisterSpecSet mutableCopy() {
        int len = specs.length;
        RegisterSpecSet copy = new RegisterSpecSet(len);

        for (int i = 0; i < len; i++) {
            RegisterSpec spec = specs[i];
            if (spec != null) {
                copy.put(spec);
            }
        }

        copy.size = size;

        return copy;
    }
}
