// 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.errors.Unreachable;
import com.android.tools.r8.utils.OrderedMergingIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

public class DexAnnotationDirectory extends DexItem {

  private final DexProgramClass clazz;
  private final List<DexEncodedMethod> methodAnnotations;
  private final List<DexEncodedMethod> parameterAnnotations;
  private final List<DexEncodedField> fieldAnnotations;
  private final boolean classHasOnlyInternalizableAnnotations;

  public DexAnnotationDirectory(DexProgramClass clazz) {
    this.clazz = clazz;
    this.classHasOnlyInternalizableAnnotations = clazz.hasOnlyInternalizableAnnotations();
    assert isSorted(clazz.directMethods());
    assert isSorted(clazz.virtualMethods());
    OrderedMergingIterator<DexEncodedMethod, DexMethod> methods =
        new OrderedMergingIterator<>(clazz.directMethods(), clazz.virtualMethods());
    methodAnnotations = new ArrayList<>();
    parameterAnnotations = new ArrayList<>();
    while (methods.hasNext()) {
      DexEncodedMethod method = methods.next();
      if (!method.annotations.isEmpty()) {
        methodAnnotations.add(method);
      }
      if (!method.parameterAnnotationsList.isEmpty()) {
        parameterAnnotations.add(method);
      }
    }
    assert isSorted(Arrays.asList(clazz.staticFields()));
    assert isSorted(Arrays.asList(clazz.instanceFields()));
    OrderedMergingIterator<DexEncodedField, DexField> fields =
        new OrderedMergingIterator<>(
            Arrays.asList(clazz.staticFields()), Arrays.asList(clazz.instanceFields()));
    fieldAnnotations = new ArrayList<>();
    while (fields.hasNext()) {
      DexEncodedField field = fields.next();
      if (!field.annotations.isEmpty()) {
        fieldAnnotations.add(field);
      }
    }
  }

  public DexAnnotationSet getClazzAnnotations() {
    return clazz.annotations;
  }

  public List<DexEncodedMethod> getMethodAnnotations() {
    return methodAnnotations;
  }

  public List<DexEncodedMethod> getParameterAnnotations() {
    return parameterAnnotations;
  }

  public List<DexEncodedField> getFieldAnnotations() {
    return fieldAnnotations;
  }


  /**
   * DexAnnotationDirectory of a class can be canonicalized only if a clazz has annotations and
   * does not contains annotations for his fields, methods or parameters. Indeed, if a field, method
   * or parameter has annotations in this case, the DexAnnotationDirectory can not be shared since
   * it will contains information about field, method and parameters that are only related to only
   * one class.
   */
  @Override
  public final boolean equals(Object obj) {
    if (!(obj instanceof DexAnnotationDirectory)) {
      return false;
    }
    if (classHasOnlyInternalizableAnnotations) {
      DexAnnotationDirectory other = (DexAnnotationDirectory) obj;
      if (!other.clazz.hasOnlyInternalizableAnnotations()) {
        return false;
      }
      return clazz.annotations.equals(other.clazz.annotations);
    }
    return super.equals(obj);
  }

  @Override
  public final int hashCode() {
    if (classHasOnlyInternalizableAnnotations) {
      return clazz.annotations.hashCode();
    }
    return super.hashCode();
  }

  @Override
  public void collectIndexedItems(IndexedItemCollection collection,
      DexMethod method, int instructionOffset) {
    throw new Unreachable();
  }

  @Override
  public void collectMixedSectionItems(MixedSectionCollection collection) {
    throw new Unreachable();
  }

  private static <T extends PresortedComparable<T>> boolean isSorted(
      List<? extends KeyedDexItem<T>> items) {
    return isSorted(items, KeyedDexItem::getKey);
  }

  private static <S, T extends Comparable<T>> boolean isSorted(
      List<S> items, Function<S, T> getter) {
    T current = null;
    for (S item : items) {
      T next = getter.apply(item);
      if (current != null && current.compareTo(next) >= 0) {
        return false;
      }
      current = next;
    }
    return true;
  }
}
