// Copyright (c) 2024, 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.cf.code.CfInstruction;
import com.android.tools.r8.lightir.LirCode;
import com.android.tools.r8.lightir.LirConstant;
import com.android.tools.r8.utils.ThreadUtils;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

public class ReferencedMembersCollector {

  public interface ReferencedMembersConsumer {

    void onFieldReference(DexField field, ProgramMethod context);

    void onMethodReference(DexMethod method, ProgramMethod context);
  }

  private final AppView<? extends AppInfoWithClassHierarchy> appView;
  private final ReferencedMembersConsumer consumer;

  public ReferencedMembersCollector(
      AppView<? extends AppInfoWithClassHierarchy> appView, ReferencedMembersConsumer consumer) {
    this.appView = appView;
    this.consumer = consumer;
  }

  public void run(ExecutorService executorService) throws ExecutionException {
    ThreadUtils.processItems(
        appView.appInfo().classes(),
        this::processClass,
        appView.options().getThreadingModule(),
        executorService);
  }

  private void processClass(DexProgramClass clazz) {
    clazz.forEachProgramMethodMatching(DexEncodedMethod::hasCode, this::processMethod);
  }

  private void processMethod(ProgramMethod method) {
    Code code = method.getDefinition().getCode();
    if (code.isCfCode()) {
      assert appView.isCfByteCodePassThrough(method.getDefinition());
      processCfCode(method, code.asCfCode());
    } else if (code.isDefaultInstanceInitializerCode()) {
      processDefaultInstanceInitializerCode(method);
    } else if (code.isLirCode()) {
      processLirCode(method, code.asLirCode());
    } else if (code.isThrowNullCode()) {
      // Intentionally empty.
    } else {
      assert false : code.getClass().getTypeName();
    }
  }

  private void processDefaultInstanceInitializerCode(ProgramMethod method) {
    DexMethod invokedMethod =
        DefaultInstanceInitializerCode.getParentConstructor(method, appView.dexItemFactory());
    consumer.onMethodReference(invokedMethod, method);
  }

  private void processCfCode(ProgramMethod method, CfCode code) {
    for (CfInstruction instruction : code.getInstructions()) {
      if (instruction.isFieldInstruction()) {
        consumer.onFieldReference(instruction.asFieldInstruction().getField(), method);
      } else if (instruction.isInvoke()) {
        consumer.onMethodReference(instruction.asInvoke().getMethod(), method);
      } else if (instruction.isInvokeDynamic()) {
        processCallSite(method, instruction.asInvokeDynamic().getCallSite());
      }
    }
  }

  private void processLirCode(ProgramMethod method, LirCode<Integer> code) {
    for (LirConstant constant : code.getConstantPool()) {
      if (constant instanceof DexField) {
        consumer.onFieldReference((DexField) constant, method);
      } else if (constant instanceof DexCallSite) {
        processCallSite(method, (DexCallSite) constant);
      } else if (constant instanceof DexMethod) {
        consumer.onMethodReference((DexMethod) constant, method);
      } else if (constant instanceof DexMethodHandle) {
        processMethodHandle(method, (DexMethodHandle) constant);
      }
    }
  }

  private void processCallSite(ProgramMethod method, DexCallSite callSite) {
    processMethodHandle(method, callSite.getBootstrapMethod());
    for (DexValue bootstrapArg : callSite.getBootstrapArgs()) {
      if (bootstrapArg.isDexValueField()) {
        consumer.onFieldReference(bootstrapArg.asDexValueField().getValue(), method);
      } else if (bootstrapArg.isDexValueMethod()) {
        consumer.onMethodReference(bootstrapArg.asDexValueMethod().getValue(), method);
      } else if (bootstrapArg.isDexValueMethodHandle()) {
        processMethodHandle(method, bootstrapArg.asDexValueMethodHandle().getValue());
      }
    }
  }

  private void processMethodHandle(ProgramMethod method, DexMethodHandle methodHandle) {
    if (methodHandle.isFieldHandle()) {
      consumer.onFieldReference(methodHandle.asField(), method);
    } else {
      assert methodHandle.isMethodHandle();
      consumer.onMethodReference(methodHandle.asMethod(), method);
    }
  }
}
