// 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.shaking;

import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;

import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.utils.Box;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class MainDexDirectReferenceTracer {
  private final AnnotationDirectReferenceCollector annotationDirectReferenceCollector =
      new AnnotationDirectReferenceCollector();
  private final DirectReferencesCollector codeDirectReferenceCollector;

  private final AppInfoWithClassHierarchy appInfo;
  private final Consumer<DexType> consumer;

  public MainDexDirectReferenceTracer(
      AppInfoWithClassHierarchy appInfo, Consumer<DexType> consumer) {
    this.codeDirectReferenceCollector = new DirectReferencesCollector(appInfo.dexItemFactory());
    this.appInfo = appInfo;
    this.consumer = consumer;
  }

  public void run(Set<DexType> roots) {
    for (DexType type : roots) {
      DexProgramClass clazz = asProgramClassOrNull(appInfo.definitionFor(type));
      // Should only happen for library classes, which are filtered out.
      assert clazz != null;
      consumer.accept(type);
      // Super and interfaces are live, no need to add them.
      if (!DexAnnotation.hasSynthesizedClassAnnotation(
          clazz.annotations(), appInfo.dexItemFactory())) {
        traceAnnotationsDirectDependencies(clazz.annotations());
      }
      clazz.forEachField(field -> consumer.accept(field.field.type));
      clazz.forEachProgramMethodMatching(
          definition -> {
            traceMethodDirectDependencies(definition.getReference(), consumer);
            return definition.hasCode();
          },
          method -> method.registerCodeReferences(codeDirectReferenceCollector));
    }
  }

  public void runOnCode(ProgramMethod method) {
    method.registerCodeReferences(codeDirectReferenceCollector);
  }

  public static boolean hasReferencesOutsideMainDexClasses(
      AppInfoWithClassHierarchy appInfo, ProgramMethod method, Predicate<DexType> isOutside) {
    return getFirstReferenceOutsideFromCode(appInfo, method, isOutside) != null;
  }

  public static DexProgramClass getFirstReferenceOutsideFromCode(
      AppInfoWithClassHierarchy appInfo, ProgramMethod method, Predicate<DexType> isOutside) {
    Box<DexProgramClass> result = new Box<>();
    new MainDexDirectReferenceTracer(
            appInfo,
            type -> {
              DexType baseType = type.toBaseType(appInfo.dexItemFactory());
              if (baseType.isClassType() && isOutside.test(baseType)) {
                DexClass cls = appInfo.definitionFor(baseType);
                if (cls != null && cls.isProgramClass()) {
                  result.set(cls.asProgramClass());
                }
              }
            })
        .runOnCode(method);
    return result.get();
  }

  private void traceAnnotationsDirectDependencies(DexAnnotationSet annotations) {
    annotations.collectIndexedItems(annotationDirectReferenceCollector);
  }

  private void traceMethodDirectDependencies(DexMethod method, Consumer<DexType> consumer) {
    DexProto proto = method.proto;
    consumer.accept(proto.returnType);
    for (DexType parameterType : proto.parameters.values) {
      consumer.accept(parameterType);
    }
  }

  private class DirectReferencesCollector extends UseRegistry {

    private DirectReferencesCollector(DexItemFactory factory) {
      super(factory);
    }

    @Override
    public void registerInitClass(DexType clazz) {
      consumer.accept(clazz);
    }

    @Override
    public void registerInvokeVirtual(DexMethod method) {
      registerInvoke(method);
    }

    @Override
    public void registerInvokeDirect(DexMethod method) {
      registerInvoke(method);
    }

    @Override
    public void registerInvokeStatic(DexMethod method) {
      registerInvoke(method);
    }

    @Override
    public void registerInvokeInterface(DexMethod method) {
      registerInvoke(method);
    }

    @Override
    public void registerInvokeSuper(DexMethod method) {
      registerInvoke(method);
    }

    protected void registerInvoke(DexMethod method) {
      consumer.accept(method.holder);
      traceMethodDirectDependencies(method, consumer);
    }

    @Override
    public void registerInstanceFieldWrite(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerInstanceFieldRead(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerStaticFieldRead(DexField field) {
      registerFieldAccess(field);
    }

    @Override
    public void registerStaticFieldWrite(DexField field) {
      registerFieldAccess(field);
    }

    protected void registerFieldAccess(DexField field) {
      consumer.accept(field.holder);
      consumer.accept(field.type);
    }

    @Override
    public void registerNewInstance(DexType type) {
      consumer.accept(type);
    }

    @Override
    public void registerTypeReference(DexType type) {
      consumer.accept(type);
    }

    @Override
    public void registerInstanceOf(DexType type) {
      consumer.accept(type);
    }
  }

  private class AnnotationDirectReferenceCollector implements IndexedItemCollection {

    @Override
    public boolean addClass(DexProgramClass dexProgramClass) {
      consumer.accept(dexProgramClass.type);
      return false;
    }

    @Override
    public boolean addField(DexField field) {
      consumer.accept(field.holder);
      consumer.accept(field.type);
      return false;
    }

    @Override
    public boolean addMethod(DexMethod method) {
      consumer.accept(method.holder);
      addProto(method.proto);
      return false;
    }

    @Override
    public boolean addString(DexString string) {
      return false;
    }

    @Override
    public boolean addProto(DexProto proto) {
      consumer.accept(proto.returnType);
      for (DexType parameterType : proto.parameters.values) {
        consumer.accept(parameterType);
      }
      return false;
    }

    @Override
    public boolean addType(DexType type) {
      consumer.accept(type);
      return false;
    }

    @Override
    public boolean addCallSite(DexCallSite callSite) {
      throw new AssertionError("CallSite are not supported when tracing for legacy multi dex");
    }

    @Override
    public boolean addMethodHandle(DexMethodHandle methodHandle) {
      throw new AssertionError(
          "DexMethodHandle are not supported when tracing for legacy multi dex");
    }
  }
}
