/*
 * Copyright (C) 2008 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.jack.dx.dex.file;

import com.android.jack.dx.rop.annotation.Annotations;
import com.android.jack.dx.rop.annotation.AnnotationsList;
import com.android.jack.dx.rop.cst.CstMethodRef;
import com.android.jack.dx.util.AnnotatedOutput;
import com.android.jack.dx.util.Hex;
import com.android.jack.dx.util.ToHuman;

import java.util.ArrayList;

/**
 * Association of a method and its parameter annotations.
 */
public final class ParameterAnnotationStruct implements ToHuman,
    Comparable<ParameterAnnotationStruct> {
  /** {@code non-null;} the method in question */
  private final CstMethodRef method;

  /** {@code non-null;} the associated annotations list */
  private final AnnotationsList annotationsList;

  /** {@code non-null;} the associated annotations list, as an item */
  private final UniformListItem<AnnotationSetRefItem> annotationsItem;

  /**
   * Constructs an instance.
   *
   * @param method {@code non-null;} the method in question
   * @param annotationsList {@code non-null;} the associated annotations list
   */
  public ParameterAnnotationStruct(CstMethodRef method, AnnotationsList annotationsList) {
    assert method != null;
    assert annotationsList != null;
    this.method = method;
    this.annotationsList = annotationsList;

    /*
     * Construct an item for the annotations list. TODO(dx team): This
     * requires way too much copying; fix it.
     */

int size = annotationsList.size();
    ArrayList<AnnotationSetRefItem> arrayList = new ArrayList<AnnotationSetRefItem>(size);

    for (int i = 0; i < size; i++) {
      Annotations annotations = annotationsList.get(i);
      AnnotationSetItem item = new AnnotationSetItem(annotations);
      arrayList.add(new AnnotationSetRefItem(item));
    }

    this.annotationsItem =
        new UniformListItem<AnnotationSetRefItem>(ItemType.TYPE_ANNOTATION_SET_REF_LIST, arrayList);
  }

  /** {@inheritDoc} */
  @Override
  public int hashCode() {
    return method.hashCode();
  }

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

    return method.equals(((ParameterAnnotationStruct) other).method);
  }

  /** {@inheritDoc} */
  @Override
  public int compareTo(ParameterAnnotationStruct other) {
    return method.compareTo(other.method);
  }

  public void addContents(DexFile file) {
    MethodIdsSection methodIds = file.getMethodIds();
    MixedItemSection wordData = file.getWordData();

    methodIds.intern(method);
    wordData.add(annotationsItem);
  }

  public void writeTo(DexFile file, AnnotatedOutput out) {
    int methodIdx = file.getMethodIds().indexOf(method);
    int annotationsOff = annotationsItem.getAbsoluteOffset();

    if (out.annotates()) {
      out.annotate(0, "    " + method.toHuman());
      out.annotate(4, "      method_idx:      " + Hex.u4(methodIdx));
      out.annotate(4, "      annotations_off: " + Hex.u4(annotationsOff));
    }

    out.writeInt(methodIdx);
    out.writeInt(annotationsOff);
  }

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

    sb.append(method.toHuman());
    sb.append(": ");

    boolean first = true;
    for (AnnotationSetRefItem item : annotationsItem.getItems()) {
      if (first) {
        first = false;
      } else {
        sb.append(", ");
      }
      sb.append(item.toHuman());
    }

    return sb.toString();
  }

  /**
   * Gets the method this item is for.
   *
   * @return {@code non-null;} the method
   */
  public CstMethodRef getMethod() {
    return method;
  }

  /**
   * Gets the associated annotations list.
   *
   * @return {@code non-null;} the annotations list
   */
  public AnnotationsList getAnnotationsList() {
    return annotationsList;
  }
}
