// Copyright (c) 2021, 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.ir.conversion.callgraph;

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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessInfo;
import com.android.tools.r8.graph.FieldAccessInfoCollection;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

public class IRProcessingCallGraphUseRegistry<N extends NodeBase<N>> extends InvokeExtractor<N> {

  private final FieldAccessInfoCollection<?> fieldAccessInfoCollection;

  IRProcessingCallGraphUseRegistry(
      AppView<AppInfoWithLiveness> appView,
      N currentMethod,
      Function<ProgramMethod, N> nodeFactory,
      Map<DexMethod, ProgramMethodSet> possibleProgramTargetsCache,
      Predicate<ProgramMethod> targetTester) {
    super(appView, currentMethod, nodeFactory, possibleProgramTargetsCache, targetTester);
    this.fieldAccessInfoCollection = appView.appInfo().getFieldAccessInfoCollection();
  }

  protected void addClassInitializerTarget(DexProgramClass clazz) {
    assert clazz != null;
    if (clazz.hasClassInitializer()) {
      addCallEdge(clazz.getProgramClassInitializer(), false);
    }
  }

  protected void addClassInitializerTarget(DexType type) {
    assert type.isClassType();
    DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(type));
    if (clazz != null) {
      addClassInitializerTarget(clazz);
    }
  }

  private void addFieldReadEdge(ProgramMethod writer) {
    assert !writer.getDefinition().isAbstract();
    if (!targetTester.test(writer)) {
      return;
    }
    nodeFactory.apply(writer).addReaderConcurrently(currentMethod);
  }

  private void processFieldRead(DexField reference) {
    DexField rewrittenReference = appView.graphLens().lookupField(reference, getCodeLens());
    if (!rewrittenReference.getHolderType().isClassType()) {
      return;
    }

    ProgramField field = appView.appInfo().resolveField(rewrittenReference).getSingleProgramField();
    if (field == null || appView.appInfo().isPinned(field)) {
      return;
    }

    // Each static field access implicitly triggers the class initializer.
    if (field.getAccessFlags().isStatic()) {
      addClassInitializerTarget(field.getHolder());
    }

    FieldAccessInfo fieldAccessInfo = fieldAccessInfoCollection.get(field.getReference());
    if (fieldAccessInfo != null && fieldAccessInfo.hasKnownWriteContexts()) {
      if (fieldAccessInfo.getNumberOfWriteContexts() == 1) {
        fieldAccessInfo.forEachWriteContext(this::addFieldReadEdge);
      }
    }
  }

  private void processFieldWrite(DexField reference) {
    DexField rewrittenReference = appView.graphLens().lookupField(reference, getCodeLens());
    if (!rewrittenReference.getHolderType().isClassType()) {
      return;
    }

    ProgramField field = appView.appInfo().resolveField(rewrittenReference).getSingleProgramField();
    if (field == null || appView.appInfo().isPinned(field)) {
      return;
    }

    // Each static field access implicitly triggers the class initializer.
    if (field.getAccessFlags().isStatic()) {
      addClassInitializerTarget(field.getHolder());
    }
  }

  private void processInitClass(DexType type) {
    DexType rewrittenType = appView.graphLens().lookupType(type);
    DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(rewrittenType));
    if (clazz == null) {
      assert false;
      return;
    }
    addClassInitializerTarget(clazz);
  }

  @Override
  protected void processSingleTarget(ProgramMethod singleTarget, ProgramMethod context) {
    super.processSingleTarget(singleTarget, context);
    if (singleTarget.getAccessFlags().isStatic()) {
      addClassInitializerTarget(singleTarget.getHolder());
    }
  }

  @Override
  public void registerInitClass(DexType clazz) {
    processInitClass(clazz);
  }

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

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

  @Override
  public void registerInstanceOf(DexType type) {}

  @Override
  public void registerNewInstance(DexType type) {
    if (type.isClassType()) {
      addClassInitializerTarget(type);
    }
  }

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

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

  @Override
  public void registerTypeReference(DexType type) {}

  @Override
  public void registerCallSite(DexCallSite callSite) {
    registerMethodHandle(
        callSite.bootstrapMethod, MethodHandleUse.NOT_ARGUMENT_TO_LAMBDA_METAFACTORY);
  }
}
