// Copyright (c) 2025, 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;

import com.android.tools.r8.assistant.ClassInjectionHelper;
import com.android.tools.r8.assistant.runtime.EmptyReflectiveOperationReceiver;
import com.android.tools.r8.assistant.runtime.ReflectiveOperationLogger;
import com.android.tools.r8.assistant.runtime.ReflectiveOperationReceiver;
import com.android.tools.r8.assistant.runtime.ReflectiveOracle;
import com.android.tools.r8.assistant.runtime.ReflectiveOracle.Stack;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Backend;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.DumpInputFlags;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.DesugarState;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThreadUtils;
import java.util.Collections;

/**
 * This is an experimental API for injecting reflective identification callbacks into dex code. This
 * API is subject to change.
 */
@KeepForApi
public class R8AssistantCommand extends BaseCompilerCommand {

  private final String reflectiveReceiverDescriptor;

  public R8AssistantCommand(
      AndroidApp app,
      CompilationMode mode,
      ProgramConsumer programConsumer,
      int minApiLevel,
      Reporter reporter,
      String reflectiveReceiverDescriptor) {
    super(
        app,
        mode,
        programConsumer,
        StringConsumer.emptyConsumer(),
        minApiLevel,
        reporter,
        DesugarState.ON,
        false,
        false,
        (a, b) -> true,
        Collections.emptyList(),
        Collections.emptyList(),
        ThreadUtils.NOT_SPECIFIED,
        DumpInputFlags.noDump(),
        null,
        null,
        false,
        Collections.emptyList(),
        Collections.emptyList(),
        null,
        null);
    this.reflectiveReceiverDescriptor = reflectiveReceiverDescriptor;
  }

  public static Builder builder(DiagnosticsHandler reporter) {
    return new Builder(reporter);
  }

  public static Builder builder() {
    return new Builder();
  }

  @Override
  InternalOptions getInternalOptions() {
    DexItemFactory factory = new DexItemFactory();
    InternalOptions options = new InternalOptions(factory, getReporter());
    options.setMinApiLevel(AndroidApiLevel.getAndroidApiLevel(getMinApiLevel()));
    options.passthroughDexCode = true;
    options.tool = Tool.R8Assistant;
    Marker marker = new Marker(Tool.R8Assistant);
    marker.setBackend(Backend.DEX);
    marker.setMinApi(getMinApiLevel());
    options.setMarker(marker);
    options.programConsumer = getProgramConsumer();
    return options;
  }

  public String getReflectiveReceiverDescriptor() {
    return reflectiveReceiverDescriptor;
  }

  /**
   * This is an experimental API for injecting reflective identification callbacks into dex code.
   * This API is subject to change.
   */
  @KeepForApi
  public static class Builder extends BaseCompilerCommand.Builder<R8AssistantCommand, Builder> {

    private String reflectiveReceiverDescriptor;

    private Builder() {
      this(new DiagnosticsHandler() {});
    }

    @Override
    void validate() {
      if (!(getProgramConsumer() instanceof DexIndexedConsumer)) {
        getReporter().error("R8 assistant does not support CF output.");
      }
      if (!hasNativeMultidex()) {
        getReporter().error("R8 assistant requires min api >= 21");
      }
    }

    public Builder addReflectiveOperationReceiverInput(ProgramResourceProvider provider) {
      // This code is simply added to the program input, will be called by the ReflectiveOracle.
      addProgramResourceProvider(provider);
      return self();
    }

    public Builder setReflectiveReceiverClassDescriptor(String descriptor) {
      if (!DescriptorUtils.isClassDescriptor(descriptor)) {
        getReporter().error("Not a valid descriptor " + descriptor);
      }
      this.reflectiveReceiverDescriptor = descriptor;
      return self();
    }

    @Override
    CompilationMode defaultCompilationMode() {
      return CompilationMode.RELEASE;
    }

    private Builder(DiagnosticsHandler diagnosticsHandler) {
      super(diagnosticsHandler);
    }

    @Override
    Builder self() {
      return this;
    }

    @Override
    R8AssistantCommand makeCommand() {
      injectClasses(
          EmptyReflectiveOperationReceiver.class,
          ReflectiveOperationLogger.class,
          ReflectiveOperationReceiver.NameLookupType.class,
          ReflectiveOperationReceiver.ClassFlag.class,
          ReflectiveOperationReceiver.class,
          ReflectiveOracle.class,
          Stack.class);
      return new R8AssistantCommand(
          getAppBuilder().build(),
          getMode(),
          getProgramConsumer(),
          getMinApiLevel(),
          getReporter(),
          reflectiveReceiverDescriptor);
    }

    private void injectClasses(Class<?>... classes) {
      ClassInjectionHelper injectionHelper = new ClassInjectionHelper(getReporter());
      String reason = "Reflective instrumentation";
      for (Class<?> clazz : classes) {
        addClassProgramData(
            injectionHelper.getClassBytes(clazz), new SynthesizedOrigin(reason, clazz));
      }
    }
  }
}
