// 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.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import java.util.ArrayList;
import java.util.List;

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();
    methodAnnotations = new ArrayList<>();
    parameterAnnotations = new ArrayList<>();
    fieldAnnotations = new ArrayList<>();
    clazz
        .getMethodCollection()
        .forEachMethod(
            method -> {
              if (!method.annotations().isEmpty()) {
                methodAnnotations.add(method);
              }
              if (!method.parameterAnnotationsList.isEmpty()) {
                parameterAnnotations.add(method);
              }
            });
    for (DexEncodedField field : clazz.fields()) {
      if (!field.annotations().isEmpty()) {
        fieldAnnotations.add(field);
      }
    }
  }

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

  public List<DexEncodedMethod> sortMethodAnnotations(CompareToVisitor visitor) {
    methodAnnotations.sort((a, b) -> a.getReference().acceptCompareTo(b.getReference(), visitor));
    return methodAnnotations;
  }

  public List<DexEncodedMethod> sortParameterAnnotations(CompareToVisitor visitor) {
    parameterAnnotations.sort(
        (a, b) -> a.getReference().acceptCompareTo(b.getReference(), visitor));
    return parameterAnnotations;
  }

  public List<DexEncodedField> sortFieldAnnotations(CompareToVisitor visitor) {
    fieldAnnotations.sort((a, b) -> a.getReference().acceptCompareTo(b.getReference(), visitor));
    return fieldAnnotations;
  }

  /**
   * DexAnnotationDirectory of a class can be canonicalized only if a class has annotations and
   * does not contains annotations for its 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 collectMixedSectionItems(MixedSectionCollection collection) {
    throw new Unreachable();
  }
}
