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

import com.android.dexgen.rop.cst.Constant;
import com.android.dexgen.rop.cst.CstAnnotation;
import com.android.dexgen.rop.cst.CstFieldRef;
import com.android.dexgen.rop.cst.CstLiteralBits;
import com.android.dexgen.rop.cst.CstMethodRef;
import com.android.dexgen.rop.cst.CstNat;
import com.android.dexgen.rop.cst.CstType;
import com.android.dexgen.rop.cst.CstUtf8;
import com.android.dexgen.rop.cst.TypedConstant;
import com.android.dexgen.util.Hex;
import com.android.dexgen.util.MutabilityControl;
import com.android.dexgen.util.ToHuman;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeMap;

/**
 * An annotation on an element of a class. Annotations have an
 * associated type and additionally consist of a set of (name, value)
 * pairs, where the names are unique.
 */
public final class Annotation extends MutabilityControl
        implements Comparable<Annotation>, ToHuman {
    /** {@code non-null;} type of the annotation */
    private final CstType type;

    /** {@code non-null;} the visibility of the annotation */
    private final AnnotationVisibility visibility;

    /** {@code non-null;} map from names to {@link NameValuePair} instances */
    private final TreeMap<CstUtf8, NameValuePair> elements;

    /**
     * Construct an instance. It initially contains no elements.
     *
     * @param type {@code non-null;} type of the annotation
     * @param visibility {@code non-null;} the visibility of the annotation
     */
    public Annotation(CstType type, AnnotationVisibility visibility) {
        if (type == null) {
            throw new NullPointerException("type == null");
        }

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

        this.type = type;
        this.visibility = visibility;
        this.elements = new TreeMap<CstUtf8, NameValuePair>();
    }

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

        Annotation otherAnnotation = (Annotation) other;

        if (! (type.equals(otherAnnotation.type)
                        && (visibility == otherAnnotation.visibility))) {
            return false;
        }

        return elements.equals(otherAnnotation.elements);
    }

    /** {@inheritDoc} */
    public int hashCode() {
        int hash = type.hashCode();
        hash = (hash * 31) + elements.hashCode();
        hash = (hash * 31) + visibility.hashCode();
        return hash;
    }

    /** {@inheritDoc} */
    public int compareTo(Annotation other) {
        int result = type.compareTo(other.type);

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

        result = visibility.compareTo(other.visibility);

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

        Iterator<NameValuePair> thisIter = elements.values().iterator();
        Iterator<NameValuePair> otherIter = other.elements.values().iterator();

        while (thisIter.hasNext() && otherIter.hasNext()) {
            NameValuePair thisOne = thisIter.next();
            NameValuePair otherOne = otherIter.next();

            result = thisOne.compareTo(otherOne);
            if (result != 0) {
                return result;
            }
        }

        if (thisIter.hasNext()) {
            return 1;
        } else if (otherIter.hasNext()) {
            return -1;
        }

        return 0;
    }

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

    /** {@inheritDoc} */
    public String toHuman() {
        StringBuilder sb = new StringBuilder();

        sb.append(visibility.toHuman());
        sb.append("-annotation ");
        sb.append(type.toHuman());
        sb.append(" {");

        boolean first = true;
        for (NameValuePair pair : elements.values()) {
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            sb.append(pair.getName().toHuman());
            sb.append(": ");
            sb.append(pair.getValue().toHuman());
        }

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

    /**
     * Gets the type of this instance.
     *
     * @return {@code non-null;} the type
     */
    public CstType getType() {
        return type;
    }

    /**
     * Gets the visibility of this instance.
     *
     * @return {@code non-null;} the visibility
     */
    public AnnotationVisibility getVisibility() {
        return visibility;
    }

    /**
     * Put an element into the set of (name, value) pairs for this instance.
     * If there is a preexisting element with the same name, it will be
     * replaced by this method.
     *
     * @param pair {@code non-null;} the (name, value) pair to place into this instance
     */
    public void put(NameValuePair pair) {
        throwIfImmutable();

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

        elements.put(pair.getName(), pair);
    }

    /**
     * Add an element to the set of (name, value) pairs for this instance.
     * It is an error to call this method if there is a preexisting element
     * with the same name.
     *
     * @param pair {@code non-null;} the (name, value) pair to add to this instance
     */
    public void add(NameValuePair pair) {
        throwIfImmutable();

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

        CstUtf8 name = pair.getName();

        if (elements.get(name) != null) {
            throw new IllegalArgumentException("name already added: " + name);
        }

        elements.put(name, pair);
    }

    /**
     * Gets the set of name-value pairs contained in this instance. The
     * result is always unmodifiable.
     *
     * @return {@code non-null;} the set of name-value pairs
     */
    public Collection<NameValuePair> getNameValuePairs() {
        return Collections.unmodifiableCollection(elements.values());
    }
}
