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

import com.android.dexgen.rop.cst.Constant;
import com.android.dexgen.rop.cst.CstUtf8;
import com.android.dexgen.rop.type.Type;
import com.android.dexgen.rop.type.TypeBearer;
import com.android.dexgen.util.ToHuman;

import java.util.HashMap;

/**
 * Combination of a register number and a type, used as the sources and
 * destinations of register-based operations.
 */
public final class RegisterSpec
        implements TypeBearer, ToHuman, Comparable<RegisterSpec> {
    /** {@code non-null;} string to prefix register numbers with */
    public static final String PREFIX = "v";

    /** {@code non-null;} intern table for instances */
    private static final HashMap<Object, RegisterSpec> theInterns =
        new HashMap<Object, RegisterSpec>(1000);

    /** {@code non-null;} common comparison instance used while interning */
    private static final ForComparison theInterningItem = new ForComparison();

    /** {@code >= 0;} register number */
    private final int reg;

    /** {@code non-null;} type loaded or stored */
    private final TypeBearer type;

    /** {@code null-ok;} local variable info associated with this register, if any */
    private final LocalItem local;

    /**
     * Intern the given triple as an instance of this class.
     *
     * @param reg {@code >= 0;} the register number
     * @param type {@code non-null;} the type (or possibly actual value) which
     * is loaded from or stored to the indicated register
     * @param local {@code null-ok;} the associated local variable, if any
     * @return {@code non-null;} an appropriately-constructed instance
     */
    private static RegisterSpec intern(int reg, TypeBearer type,
            LocalItem local) {
        theInterningItem.set(reg, type, local);
        RegisterSpec found = theInterns.get(theInterningItem);

        if (found != null) {
            return found;
        }

        found = theInterningItem.toRegisterSpec();
        theInterns.put(found, found);
        return found;
    }

    /**
     * Returns an instance for the given register number and type, with
     * no variable info. This method is allowed to return shared
     * instances (but doesn't necessarily do so).
     *
     * @param reg {@code >= 0;} the register number
     * @param type {@code non-null;} the type (or possibly actual value) which
     * is loaded from or stored to the indicated register
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static RegisterSpec make(int reg, TypeBearer type) {
        return intern(reg, type, null);
    }

    /**
     * Returns an instance for the given register number, type, and
     * variable info. This method is allowed to return shared
     * instances (but doesn't necessarily do so).
     *
     * @param reg {@code >= 0;} the register number
     * @param type {@code non-null;} the type (or possibly actual value) which
     * is loaded from or stored to the indicated register
     * @param local {@code non-null;} the associated local variable
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static RegisterSpec make(int reg, TypeBearer type,
            LocalItem local) {
        if (local == null) {
            throw new NullPointerException("local  == null");
        }

        return intern(reg, type, local);
    }

    /**
     * Returns an instance for the given register number, type, and
     * variable info. This method is allowed to return shared
     * instances (but doesn't necessarily do so).
     *
     * @param reg {@code >= 0;} the register number
     * @param type {@code non-null;} the type (or possibly actual value) which
     * is loaded from or stored to the indicated register
     * @param local {@code null-ok;} the associated variable info or null for
     * none
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public static RegisterSpec makeLocalOptional(
            int reg, TypeBearer type, LocalItem local) {

        return intern(reg, type, local);
    }

    /**
     * Gets the string form for the given register number.
     *
     * @param reg {@code >= 0;} the register number
     * @return {@code non-null;} the string form
     */
    public static String regString(int reg) {
        return PREFIX + reg;
    }

    /**
     * Constructs an instance. This constructor is private. Use
     * {@link #make}.
     *
     * @param reg {@code >= 0;} the register number
     * @param type {@code non-null;} the type (or possibly actual value) which
     * is loaded from or stored to the indicated register
     * @param local {@code null-ok;} the associated local variable, if any
     */
    private RegisterSpec(int reg, TypeBearer type, LocalItem local) {
        if (reg < 0) {
            throw new IllegalArgumentException("reg < 0");
        }

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

        this.reg = reg;
        this.type = type;
        this.local = local;
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object other) {
        if (!(other instanceof RegisterSpec)) {
            if (other instanceof ForComparison) {
                ForComparison fc = (ForComparison) other;
                return equals(fc.reg, fc.type, fc.local);
            }
            return false;
        }

        RegisterSpec spec = (RegisterSpec) other;
        return equals(spec.reg, spec.type, spec.local);
    }

    /**
     * Like {@code equals}, but only consider the simple types of the
     * registers. That is, this compares {@code getType()} on the types
     * to ignore whatever arbitrary extra stuff might be carried around
     * by an outer {@link TypeBearer}.
     *
     * @param other {@code null-ok;} spec to compare to
     * @return {@code true} iff {@code this} and {@code other} are equal
     * in the stated way
     */
    public boolean equalsUsingSimpleType(RegisterSpec other) {
        if (!matchesVariable(other)) {
            return false;
        }

        return (reg == other.reg);
    }

    /**
     * Like {@link #equalsUsingSimpleType} but ignoring the register number.
     * This is useful to determine if two instances refer to the "same"
     * local variable.
     *
     * @param other {@code null-ok;} spec to compare to
     * @return {@code true} iff {@code this} and {@code other} are equal
     * in the stated way
     */
    public boolean matchesVariable(RegisterSpec other) {
        if (other == null) {
            return false;
        }

        return type.getType().equals(other.type.getType())
            && ((local == other.local)
                    || ((local != null) && local.equals(other.local)));
    }

    /**
     * Helper for {@link #equals} and {@link #ForComparison.equals},
     * which actually does the test.
     *
     * @param reg value of the instance variable, for another instance
     * @param type value of the instance variable, for another instance
     * @param local value of the instance variable, for another instance
     * @return whether this instance is equal to one with the given
     * values
     */
    private boolean equals(int reg, TypeBearer type, LocalItem local) {
        return (this.reg == reg)
            && this.type.equals(type)
            && ((this.local == local)
                    || ((this.local != null) && this.local.equals(local)));
    }

    /**
     * Compares by (in priority order) register number, unwrapped type
     * (that is types not {@link TypeBearer}s, and local info.
     *
     * @param other {@code non-null;} spec to compare to
     * @return {@code -1..1;} standard result of comparison
     */
    public int compareTo(RegisterSpec other) {
        if (this.reg < other.reg) {
            return -1;
        } else if (this.reg > other.reg) {
            return 1;
        }

        int compare = type.getType().compareTo(other.type.getType());

        if (compare != 0) {
            return compare;
        }

        if (this.local == null) {
            return (other.local == null) ? 0 : -1;
        } else if (other.local == null) {
            return 1;
        }

        return this.local.compareTo(other.local);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return hashCodeOf(reg, type, local);
    }

    /**
     * Helper for {@link #hashCode} and {@link #ForComparison.hashCode},
     * which actually does the calculation.
     *
     * @param reg value of the instance variable
     * @param type value of the instance variable
     * @param local value of the instance variable
     * @return the hash code
     */
    private static int hashCodeOf(int reg, TypeBearer type, LocalItem local) {
        int hash = (local != null) ? local.hashCode() : 0;

        hash = (hash * 31 + type.hashCode()) * 31 + reg;
        return hash;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return toString0(false);
    }

    /** {@inheritDoc} */
    public String toHuman() {
        return toString0(true);
    }

    /** {@inheritDoc} */
    public Type getType() {
        return type.getType();
    }

    /** {@inheritDoc} */
    public TypeBearer getFrameType() {
        return type.getFrameType();
    }

    /** {@inheritDoc} */
    public final int getBasicType() {
        return type.getBasicType();
    }

    /** {@inheritDoc} */
    public final int getBasicFrameType() {
        return type.getBasicFrameType();
    }

    /** {@inheritDoc} */
    public final boolean isConstant() {
        return false;
    }

    /**
     * Gets the register number.
     *
     * @return {@code >= 0;} the register number
     */
    public int getReg() {
        return reg;
    }

    /**
     * Gets the type (or actual value) which is loaded from or stored
     * to the register associated with this instance.
     *
     * @return {@code non-null;} the type
     */
    public TypeBearer getTypeBearer() {
        return type;
    }

    /**
     * Gets the variable info associated with this instance, if any.
     *
     * @return {@code null-ok;} the variable info, or {@code null} if this
     * instance has none
     */
    public LocalItem getLocalItem() {
        return local;
    }

    /**
     * Gets the next available register number after the one in this
     * instance. This is equal to the register number plus the width
     * (category) of the type used. Among other things, this may also
     * be used to determine the minimum required register count
     * implied by this instance.
     *
     * @return {@code >= 0;} the required registers size
     */
    public int getNextReg() {
        return reg + getCategory();
    }

    /**
     * Gets the category of this instance's type. This is just a convenient
     * shorthand for {@code getType().getCategory()}.
     *
     * @see #isCategory1
     * @see #isCategory2
     * @return {@code 1..2;} the category of this instance's type
     */
    public int getCategory() {
        return type.getType().getCategory();
    }

    /**
     * Gets whether this instance's type is category 1. This is just a
     * convenient shorthand for {@code getType().isCategory1()}.
     *
     * @see #getCategory
     * @see #isCategory2
     * @return whether or not this instance's type is of category 1
     */
    public boolean isCategory1() {
        return type.getType().isCategory1();
    }

    /**
     * Gets whether this instance's type is category 2. This is just a
     * convenient shorthand for {@code getType().isCategory2()}.
     *
     * @see #getCategory
     * @see #isCategory1
     * @return whether or not this instance's type is of category 2
     */
    public boolean isCategory2() {
        return type.getType().isCategory2();
    }

    /**
     * Gets the string form for just the register number of this instance.
     *
     * @return {@code non-null;} the register string form
     */
    public String regString() {
        return regString(reg);
    }

    /**
     * Returns an instance that is the intersection between this instance
     * and the given one, if any. The intersection is defined as follows:
     *
     * <ul>
     *   <li>If {@code other} is {@code null}, then the result
     *     is {@code null}.
     *   <li>If the register numbers don't match, then the intersection
     *     is {@code null}. Otherwise, the register number of the
     *     intersection is the same as the one in the two instances.</li>
     *   <li>If the types returned by {@code getType()} are not
     *     {@code equals()}, then the intersection is null.</li>
     *   <li>If the type bearers returned by {@code getTypeBearer()}
     *     are {@code equals()}, then the intersection's type bearer
     *     is the one from this instance. Otherwise, the intersection's
     *     type bearer is the {@code getType()} of this instance.</li>
     *   <li>If the locals are {@code equals()}, then the local info
     *     of the intersection is the local info of this instance. Otherwise,
     *     the local info of the intersection is {@code null}.</li>
     * </ul>
     *
     * @param other {@code null-ok;} instance to intersect with (or {@code null})
     * @param localPrimary whether local variables are primary to the
     * intersection; if {@code true}, then the only non-null
     * results occur when registers being intersected have equal local
     * infos (or both have {@code null} local infos)
     * @return {@code null-ok;} the intersection
     */
    public RegisterSpec intersect(RegisterSpec other, boolean localPrimary) {
        if (this == other) {
            // Easy out.
            return this;
        }

        if ((other == null) || (reg != other.getReg())) {
            return null;
        }

        LocalItem resultLocal =
            ((local == null) || !local.equals(other.getLocalItem()))
            ? null : local;
        boolean sameName = (resultLocal == local);

        if (localPrimary && !sameName) {
            return null;
        }

        Type thisType = getType();
        Type otherType = other.getType();

        // Note: Types are always interned.
        if (thisType != otherType) {
            return null;
        }

        TypeBearer resultTypeBearer =
            type.equals(other.getTypeBearer()) ? type : thisType;

        if ((resultTypeBearer == type) && sameName) {
            // It turns out that the intersection is "this" after all.
            return this;
        }

        return (resultLocal == null) ? make(reg, resultTypeBearer) :
            make(reg, resultTypeBearer, resultLocal);
    }

    /**
     * Returns an instance that is identical to this one, except that the
     * register number is replaced by the given one.
     *
     * @param newReg {@code >= 0;} the new register number
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public RegisterSpec withReg(int newReg) {
        if (reg == newReg) {
            return this;
        }

        return makeLocalOptional(newReg, type, local);
    }

    /**
     * Returns an instance that is identical to this one, except that
     * the type is replaced by the given one.
     *
     * @param newType {@code non-null;} the new type
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public RegisterSpec withType(TypeBearer newType) {
        return makeLocalOptional(reg, newType, local);
    }

    /**
     * Returns an instance that is identical to this one, except that the
     * register number is offset by the given amount.
     *
     * @param delta the amount to offset the register number by
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public RegisterSpec withOffset(int delta) {
        if (delta == 0) {
            return this;
        }

        return withReg(reg + delta);
    }

    /**
     * Returns an instance that is identical to this one, except that
     * the type bearer is replaced by the actual underlying type
     * (thereby stripping off non-type information) with any
     * initialization information stripped away as well.
     *
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public RegisterSpec withSimpleType() {
        TypeBearer orig = type;
        Type newType;

        if (orig instanceof Type) {
            newType = (Type) orig;
        } else {
            newType = orig.getType();
        }

        if (newType.isUninitialized()) {
            newType = newType.getInitializedType();
        }

        if (newType == orig) {
            return this;
        }

        return makeLocalOptional(reg, newType, local);
    }

    /**
     * Returns an instance that is identical to this one except that the
     * local variable is as specified in the parameter.
     *
     * @param local {@code null-ok;} the local item or null for none
     * @return an appropriate instance
     */
    public RegisterSpec withLocalItem(LocalItem local) {
        if ((this.local== local)
                    || ((this.local != null) && this.local.equals(local))) {

            return this;
        }

        return makeLocalOptional(reg, type, local);
    }


    /**
     * Helper for {@link #toString} and {@link #toHuman}.
     *
     * @param human whether to be human-oriented
     * @return {@code non-null;} the string form
     */
    private String toString0(boolean human) {
        StringBuffer sb = new StringBuffer(40);

        sb.append(regString());
        sb.append(":");

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

        Type justType = type.getType();
        sb.append(justType);

        if (justType != type) {
            sb.append("=");
            if (human && (type instanceof Constant)) {
                sb.append(((Constant) type).toHuman());
            } else {
                sb.append(type);
            }
        }

        return sb.toString();
    }

    /**
     * Holder of register spec data for the purposes of comparison (so that
     * {@code RegisterSpec} itself can still keep {@code final}
     * instance variables.
     */
    private static class ForComparison {
        /** {@code >= 0;} register number */
        private int reg;

        /** {@code non-null;} type loaded or stored */
        private TypeBearer type;

        /**
         * {@code null-ok;} local variable associated with this
         * register, if any
         */
        private LocalItem local;

        /**
         * Set all the instance variables.
         *
         * @param reg {@code >= 0;} the register number
         * @param type {@code non-null;} the type (or possibly actual
         * value) which is loaded from or stored to the indicated
         * register
         * @param local {@code null-ok;} the associated local variable, if any
         * @return {@code non-null;} an appropriately-constructed instance
         */
        public void set(int reg, TypeBearer type, LocalItem local) {
            this.reg = reg;
            this.type = type;
            this.local = local;
        }

        /**
         * Construct a {@code RegisterSpec} of this instance's
         * contents.
         *
         * @return {@code non-null;} an appropriately-constructed instance
         */
        public RegisterSpec toRegisterSpec() {
            return new RegisterSpec(reg, type, local);
        }

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

            RegisterSpec spec = (RegisterSpec) other;
            return spec.equals(reg, type, local);
        }

        /** {@inheritDoc} */
        @Override
        public int hashCode() {
            return hashCodeOf(reg, type, local);
        }
    }
}
