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

import com.android.dx.rop.type.Type;

/**
 * Constants of type {@code CONSTANT_NameAndType_info}.
 */
public final class CstNat extends Constant {
    /**
     * {@code non-null;} the instance for name {@code TYPE} and descriptor
     * {@code java.lang.Class}, which is useful when dealing with
     * wrapped primitives
     */
    public static final CstNat PRIMITIVE_TYPE_NAT =
        new CstNat(new CstString("TYPE"),
                   new CstString("Ljava/lang/Class;"));

    /** {@code non-null;} the name */
    private final CstString name;

    /** {@code non-null;} the descriptor (type) */
    private final CstString descriptor;

    /**
     * Constructs an instance.
     *
     * @param name {@code non-null;} the name
     * @param descriptor {@code non-null;} the descriptor
     */
    public CstNat(CstString name, CstString descriptor) {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

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

        this.name = name;
        this.descriptor = descriptor;
    }

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

        CstNat otherNat = (CstNat) other;
        return name.equals(otherNat.name) &&
            descriptor.equals(otherNat.descriptor);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return (name.hashCode() * 31) ^ descriptor.hashCode();
    }

    /** {@inheritDoc} */
    @Override
    protected int compareTo0(Constant other) {
        CstNat otherNat = (CstNat) other;
        int cmp = name.compareTo(otherNat.name);

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

        return descriptor.compareTo(otherNat.descriptor);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return "nat{" + toHuman() + '}';
    }

    /** {@inheritDoc} */
    @Override
    public String typeName() {
        return "nat";
    }

    /** {@inheritDoc} */
    @Override
    public boolean isCategory2() {
        return false;
    }

    /**
     * Gets the name.
     *
     * @return {@code non-null;} the name
     */
    public CstString getName() {
        return name;
    }

    /**
     * Gets the descriptor.
     *
     * @return {@code non-null;} the descriptor
     */
    public CstString getDescriptor() {
        return descriptor;
    }

    /**
     * Returns an unadorned but human-readable version of the name-and-type
     * value.
     *
     * @return {@code non-null;} the human form
     */
    public String toHuman() {
        return name.toHuman() + ':' + descriptor.toHuman();
    }

    /**
     * Gets the field type corresponding to this instance's descriptor.
     * This method is only valid to call if the descriptor in fact describes
     * a field (and not a method).
     *
     * @return {@code non-null;} the field type
     */
    public Type getFieldType() {
        return Type.intern(descriptor.getString());
    }

    /**
     * Gets whether this instance has the name of a standard instance
     * initialization method. This is just a convenient shorthand for
     * {@code getName().getString().equals("<init>")}.
     *
     * @return {@code true} iff this is a reference to an
     * instance initialization method
     */
    public final boolean isInstanceInit() {
        return name.getString().equals("<init>");
    }

    /**
     * Gets whether this instance has the name of a standard class
     * initialization method. This is just a convenient shorthand for
     * {@code getName().getString().equals("<clinit>")}.
     *
     * @return {@code true} iff this is a reference to an
     * instance initialization method
     */
    public final boolean isClassInit() {
        return name.getString().equals("<clinit>");
    }
}
