// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;

import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.structural.StructuralAccept;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;

public class DexEncodedAnnotation extends DexItem implements StructuralItem<DexEncodedAnnotation> {

  private static final int UNSORTED = 0;

  public final DexType type;
  public final DexAnnotationElement[] elements;

  private int sorted = UNSORTED;

  private static void specify(StructuralSpecification<DexEncodedAnnotation, ?> spec) {
    spec.withItem(a -> a.type).withItemArray(a -> a.elements);
  }

  public DexEncodedAnnotation(DexType type, DexAnnotationElement[] elements) {
    this.type = type;
    this.elements = elements;
  }

  @Override
  public DexEncodedAnnotation self() {
    return this;
  }

  @Override
  public StructuralAccept<DexEncodedAnnotation> getStructuralAccept() {
    return DexEncodedAnnotation::specify;
  }

  public void collectIndexedItems(IndexedItemCollection indexedItems) {
    type.collectIndexedItems(indexedItems);
    for (DexAnnotationElement element : elements) {
      element.collectIndexedItems(indexedItems);
    }
  }

  public void forEachElement(Consumer<DexAnnotationElement> consumer) {
    for (DexAnnotationElement element : elements) {
      consumer.accept(element);
    }
  }

  public DexAnnotationElement getElement(int i) {
    return elements[i];
  }

  public int getNumberOfElements() {
    return elements.length;
  }

  @Override
  void collectMixedSectionItems(MixedSectionCollection mixedItems) {
    // Should never be called.
    assert false;
  }

  @Override
  public String toString() {
    return "Encoded annotation " + type + " " + Arrays.toString(elements);
  }

  @Override
  public int hashCode() {
    return type.hashCode() * 7 + Arrays.hashCode(elements);
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (other instanceof DexEncodedAnnotation) {
      DexEncodedAnnotation that = (DexEncodedAnnotation) other;
      return that.type.equals(type) && Arrays.equals(that.elements, elements);
    }
    return false;
  }

  public void sort() {
    if (sorted != UNSORTED) {
      assert sorted == sortedHashCode();
      return;
    }
    Arrays.sort(elements, (a, b) -> a.name.compareTo(b.name));
    for (DexAnnotationElement element : elements) {
      element.value.sort();
    }
    sorted = sortedHashCode();
  }

  private int sortedHashCode() {
    int hashCode = hashCode();
    return hashCode == UNSORTED ? 1 : hashCode;
  }

  public DexEncodedAnnotation rewrite(
      Function<DexType, DexType> typeRewriter,
      Function<DexAnnotationElement, DexAnnotationElement> elementRewriter) {
    DexType rewrittenType = typeRewriter.apply(type);
    DexAnnotationElement[] rewrittenElements =
        ArrayUtils.map(DexAnnotationElement[].class, elements, elementRewriter);
    if (rewrittenType == type && rewrittenElements == elements) {
      return this;
    }
    return new DexEncodedAnnotation(rewrittenType, rewrittenElements);
  }
}
