// Copyright (c) 2023, 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.BaseCommand.LibraryInputOrigin;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.utils.AbortException;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionDiagnostic;
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.StringDiagnostic;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

/**
 * Immutable command structure for an invocation of the {@link GlobalSyntheticsGenerator} compiler.
 */
@KeepForApi
public final class GlobalSyntheticsGeneratorCommand {

  private final GlobalSyntheticsConsumer globalsConsumer;
  private final Reporter reporter;
  private final int minApiLevel;
  private final boolean classfileDesugaringOnly;

  private final boolean printHelp;
  private final boolean printVersion;

  private final AndroidApp inputApp;

  private final DexItemFactory factory = new DexItemFactory();

  private GlobalSyntheticsGeneratorCommand(
      AndroidApp inputApp,
      GlobalSyntheticsConsumer globalsConsumer,
      Reporter reporter,
      int minApiLevel,
      boolean classfileDesugaringOnly) {
    this.inputApp = inputApp;
    this.globalsConsumer = globalsConsumer;
    this.minApiLevel = minApiLevel;
    this.classfileDesugaringOnly = classfileDesugaringOnly;
    this.reporter = reporter;
    this.printHelp = false;
    this.printVersion = false;
  }

  private GlobalSyntheticsGeneratorCommand(boolean printHelp, boolean printVersion) {
    this.printHelp = printHelp;
    this.printVersion = printVersion;

    this.inputApp = null;
    this.globalsConsumer = null;
    this.minApiLevel = AndroidApiLevel.B.getLevel();
    this.classfileDesugaringOnly = false;

    reporter = new Reporter();
  }

  public AndroidApp getInputApp() {
    return inputApp;
  }

  public boolean isPrintHelp() {
    return printHelp;
  }

  public boolean isPrintVersion() {
    return printVersion;
  }

  /**
   * Parse the GlobalSyntheticsGenerator command-line.
   *
   * <p>Parsing will set the supplied options or their default value if they have any.
   *
   * @param args Command-line arguments array.
   * @param origin Origin description of the command-line arguments.
   * @return GlobalSyntheticsGenerator command builder with state according to parsed command line.
   */
  public static Builder parse(String[] args, Origin origin) {
    return GlobalSyntheticsGeneratorCommandParser.parse(args, origin);
  }

  /**
   * Parse the GlobalSyntheticsGenerator command-line.
   *
   * <p>Parsing will set the supplied options or their default value if they have any.
   *
   * @param args Command-line arguments array.
   * @param origin Origin description of the command-line arguments.
   * @param handler Custom defined diagnostics handler.
   * @return GlobalSyntheticsGenerator command builder with state according to parsed command line.
   */
  public static Builder parse(String[] args, Origin origin, DiagnosticsHandler handler) {
    return GlobalSyntheticsGeneratorCommandParser.parse(args, origin, handler);
  }

  protected static class DefaultR8DiagnosticsHandler implements DiagnosticsHandler {

    @Override
    public void error(Diagnostic error) {
      if (error instanceof DexFileOverflowDiagnostic) {
        DexFileOverflowDiagnostic overflowDiagnostic = (DexFileOverflowDiagnostic) error;
        DiagnosticsHandler.super.error(
            new StringDiagnostic(
                overflowDiagnostic.getDiagnosticMessage()
                    + ". Library too large. GlobalSyntheticsGenerator can only produce a single"
                    + " .dex file"));
        return;
      }
      DiagnosticsHandler.super.error(error);
    }
  }

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

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

  InternalOptions getInternalOptions() {
    InternalOptions internal = new InternalOptions(factory, reporter);
    assert !internal.debug;
    assert !internal.minimalMainDex;
    internal.setMinApiLevel(AndroidApiLevel.getAndroidApiLevel(minApiLevel));
    assert internal.retainCompileTimeAnnotations;
    internal.intermediate = true;
    internal.programConsumer =
        classfileDesugaringOnly ? new ThrowingCfConsumer() : new ThrowingDexConsumer();
    internal.setGlobalSyntheticsConsumer(globalsConsumer);
    if (classfileDesugaringOnly) {
      internal.apiModelingOptions().disableApiCallerIdentification();
      internal.apiModelingOptions().disableOutliningAndStubbing();
    }

    // Assert and fixup defaults.
    assert !internal.isShrinking();
    assert !internal.isMinifying();
    assert !internal.passthroughDexCode;

    internal.tool = Tool.GlobalSyntheticsGenerator;
    internal.desugarState = DesugarState.ON;
    internal.enableVarHandleDesugaring = true;

    internal.getArtProfileOptions().setEnableCompletenessCheckForTesting(false);

    return internal;
  }

  private static class ThrowingCfConsumer implements ClassFileConsumer {

    @Override
    public void accept(ByteDataView data, String descriptor, DiagnosticsHandler handler) {
      throw new Unreachable("Unexpected attempt to write a non-global artifact");
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      // Nothing to do.
    }
  }

  private static class ThrowingDexConsumer implements DexIndexedConsumer {

    @Override
    public void accept(
        int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
      throw new Unreachable("Unexpected attempt to write a non-global artifact");
    }

    @Override
    public void finished(DiagnosticsHandler handler) {
      // Nothing to do.
    }
  }

  /**
   * Builder for constructing a GlobalSyntheticsGeneratorCommand.
   *
   * <p>A builder is obtained by calling {@link GlobalSyntheticsGeneratorCommand#builder}.
   */
  @KeepForApi
  public static class Builder {

    private GlobalSyntheticsConsumer globalsConsumer = null;
    private final Reporter reporter;
    private int minApiLevel = AndroidApiLevel.B.getLevel();
    private boolean classfileDesugaringOnly = false;
    private boolean printHelp = false;
    private boolean printVersion = false;
    private final AndroidApp.Builder appBuilder = AndroidApp.builder();

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

    private Builder(DiagnosticsHandler diagnosticsHandler) {
      this.reporter = new Reporter(diagnosticsHandler);
    }

    /** Set the min api level. */
    public Builder setMinApiLevel(int minApiLevel) {
      this.minApiLevel = minApiLevel;
      return this;
    }

    public Builder setClassfileDesugaringOnly(boolean value) {
      this.classfileDesugaringOnly = value;
      return this;
    }

    /** Set the value of the print-help flag. */
    public Builder setPrintHelp(boolean printHelp) {
      this.printHelp = printHelp;
      return this;
    }

    /** Set the value of the print-version flag. */
    public Builder setPrintVersion(boolean printVersion) {
      this.printVersion = printVersion;
      return this;
    }

    /** Add library file resources. */
    public Builder addLibraryFiles(Path... files) {
      addLibraryFiles(Arrays.asList(files));
      return this;
    }

    /** Add library file resources. */
    public Builder addLibraryFiles(Collection<Path> files) {
      guard(
          () -> {
            for (Path path : files) {
              try {
                appBuilder.addLibraryFile(path);
              } catch (CompilationError e) {
                error(new LibraryInputOrigin(path), e);
              }
            }
          });
      return this;
    }

    /** Set a destination to write the resulting global synthetics output file. */
    public Builder setGlobalSyntheticsOutput(Path path) {
      return setGlobalSyntheticsConsumer(
          new GlobalSyntheticsConsumer() {

            private boolean written = false;

            @Override
            public synchronized void accept(
                ByteDataView data, ClassReference context, DiagnosticsHandler handler) {
              if (written) {
                throw new Unreachable("Unexpected attempt to repeatedly write global synthetics");
              }
              written = true;
              try {
                Files.write(path, data.copyByteData());
              } catch (IOException e) {
                throw new RuntimeException(e);
              }
            }
          });
    }

    /** Set a consumer for obtaining the resulting global synthetics output. */
    public Builder setGlobalSyntheticsConsumer(GlobalSyntheticsConsumer globalsConsumer) {
      this.globalsConsumer = globalsConsumer;
      return this;
    }

    public GlobalSyntheticsGeneratorCommand build() {
      validate();
      if (isPrintHelpOrPrintVersion()) {
        return new GlobalSyntheticsGeneratorCommand(printHelp, printVersion);
      }
      return new GlobalSyntheticsGeneratorCommand(
          appBuilder.build(), globalsConsumer, reporter, minApiLevel, classfileDesugaringOnly);
    }

    private boolean isPrintHelpOrPrintVersion() {
      return printHelp || printVersion;
    }

    private void validate() {
      if (isPrintHelpOrPrintVersion()) {
        return;
      }
      if (globalsConsumer == null) {
        reporter.error("GlobalSyntheticsGenerator does not support compiling without output");
      }
    }

    // Helper to guard and handle exceptions.
    private void guard(Runnable action) {
      try {
        action.run();
      } catch (CompilationError e) {
        reporter.error(e.toStringDiagnostic());
      } catch (AbortException e) {
        // Error was reported and exception will be thrown by build.
      }
    }

    /** Signal an error. */
    public void error(Diagnostic diagnostic) {
      reporter.error(diagnostic);
    }

    // Helper to signify an error.
    public void error(Origin origin, Throwable throwable) {
      reporter.error(new ExceptionDiagnostic(throwable, origin));
    }
  }
}
