// Copyright (c) 2018, 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.graph.DexAnnotation.AnnotatedKind;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

/**
 * A common interface for {@link DexClass}, {@link DexEncodedField}, and {@link DexEncodedMethod}.
 */
public abstract class DexDefinition extends DexItem {

  private DexAnnotationSet annotations;

  public DexDefinition(DexAnnotationSet annotations) {
    assert annotations != null : "Should use DexAnnotationSet.THE_EMPTY_ANNOTATIONS_SET";
    this.annotations = annotations;
  }

  public boolean hasAnnotations() {
    return !annotations().isEmpty();
  }

  // Also returns true if a method has parameter annotations.
  public boolean hasAnyAnnotations() {
    return hasAnnotations();
  }

  public DexAnnotationSet annotations() {
    return annotations;
  }

  public abstract AccessFlags<?> getAccessFlags();

  public void clearAnnotations() {
    setAnnotations(DexAnnotationSet.empty());
  }

  public void clearAllAnnotations() {
    clearAnnotations();
  }

  public void setAnnotations(DexAnnotationSet annotations) {
    this.annotations = annotations;
  }

  public void removeAnnotations(Predicate<DexAnnotation> predicate) {
    setAnnotations(annotations().removeIf(predicate));
  }

  public void rewriteAllAnnotations(
      BiFunction<DexAnnotation, AnnotatedKind, DexAnnotation> rewriter) {
    setAnnotations(
        annotations().rewrite(annotation -> rewriter.apply(annotation, AnnotatedKind.from(this))));
  }

  public DexClass asClass() {
    return null;
  }

  public boolean isDexClass() {
    return false;
  }

  public DexClass asDexClass() {
    return null;
  }

  public boolean isProgramClass() {
    return false;
  }

  public DexProgramClass asProgramClass() {
    return null;
  }

  public boolean isDexEncodedMember() {
    return false;
  }

  public DexEncodedMember<?, ?> asDexEncodedMember() {
    return null;
  }

  public boolean isDexEncodedField() {
    return false;
  }

  public DexEncodedField asDexEncodedField() {
    return null;
  }

  public boolean isDexEncodedMethod() {
    return false;
  }

  public DexEncodedMethod asDexEncodedMethod() {
    return null;
  }

  public abstract DexReference getReference();

  private static <T> Stream<T> filter(
      Stream<DexDefinition> stream, Predicate<DexDefinition> pred, Function<DexDefinition, T> f) {
    return stream.filter(pred).map(f);
  }

  public static Stream<DexEncodedField> filterDexEncodedField(Stream<DexDefinition> stream) {
    return filterDexEncodedField(stream, DexDefinition::asDexEncodedField);
  }

  public static <T> Stream<T> filterDexEncodedField(
      Stream<DexDefinition> stream, Function<DexEncodedField, T> transform) {
    return filter(
        stream,
        DexDefinition::isDexEncodedField,
        field -> transform.apply(field.asDexEncodedField()));
  }

  public static Stream<DexEncodedMethod> filterDexEncodedMethod(Stream<DexDefinition> stream) {
    return filterDexEncodedMethod(stream, DexDefinition::asDexEncodedMethod);
  }

  public static <T> Stream<T> filterDexEncodedMethod(
      Stream<DexDefinition> stream, Function<DexEncodedMethod, T> transform) {
    return filter(
        stream,
        DexDefinition::isDexEncodedMethod,
        field -> transform.apply(field.asDexEncodedMethod()));
  }

  public abstract boolean isStatic();

  public abstract boolean isStaticMember();

  public boolean isNotProgramDefinition(AppView<?> appView) {
    if (isDexClass()) {
      return asDexClass().isNotProgramClass();
    }
    DexClass clazz = appView.definitionFor(asDexEncodedMember().getHolderType());
    return clazz == null || clazz.isNotProgramClass();
  }

  public DexType getContextType() {
    return isDexClass() ? asDexClass().type : asDexEncodedMember().getHolderType();
  }
}
