// Copyright (c) 2020, 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.profile.art.ArtProfile;
import com.android.tools.r8.profile.art.ArtProfileConsumer;
import com.android.tools.r8.profile.art.ArtProfileForRewriting;
import com.android.tools.r8.profile.art.ArtProfileProvider;
import com.android.tools.r8.profile.startup.profile.StartupProfile;
import com.android.tools.r8.profile.startup.profile.StartupProfileRule;
import com.android.tools.r8.startup.StartupProfileProvider;
import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.IntBox;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import org.junit.Test;

public abstract class CommandTestBase<C extends BaseCompilerCommand> extends TestBase {

  public boolean isL8() {
    return false;
  }

  private void mapDiagnosticsMissingArguments(String... args) {
    try {
      DiagnosticsChecker.checkErrorsContains(
          "Missing argument(s) for --map-diagnostics", handler -> parse(handler, args));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void mapDiagnosticsMissingArguments() throws Exception {
    mapDiagnosticsMissingArguments("--map-diagnostics");
    mapDiagnosticsMissingArguments("--map-diagnostics", "error");
    mapDiagnosticsMissingArguments("--map-diagnostics", "warning");
    mapDiagnosticsMissingArguments("--map-diagnostics", "info");
    mapDiagnosticsMissingArguments("--map-diagnostics", "xxx");
  }

  private void mapDiagnosticsInvalidArguments(String... args) {
    try {
      DiagnosticsChecker.checkErrorsContains(
          "Invalid diagnostics level 'xxx'", handler -> parse(handler, args));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void mapDiagnosticsInvalidArguments() throws Exception {
    mapDiagnosticsInvalidArguments("--map-diagnostics", "error", "xxx");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "warning", "xxx");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "info", "xxx");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "xxx", "xxx");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "xxx", "error");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "xxx", "warning");
    mapDiagnosticsInvalidArguments("--map-diagnostics", "xxx", "info");
    mapDiagnosticsInvalidArguments("--debug", "--map-diagnostics", "error", "xxx", "--debug");
  }

  @Test
  public void mapDiagnosticsInvalidArgumentsMoreErrors() {
    try {
      DiagnosticsChecker.checkErrorsContains(
          ImmutableList.of("Invalid diagnostics level 'xxx'", "Unknown option: --xxx"),
          handler -> parse(handler, "--debug", "--map-diagnostics", "error", "xxx", "--xxx"));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void errorsToWarnings() throws Exception {
    DiagnosticsChecker.checkWarningsContains(
        "Error",
        handler -> {
          C command = parseWithRequiredArgs(handler, "--map-diagnostics", "error", "warning");
          command.getReporter().error("Error");
        });

    try {
      DiagnosticsChecker.checkErrorsContains(
          "Test diagnostic",
          handler -> {
            C command =
                parseWithRequiredArgs(handler, "--map-diagnostics:a.b.C", "error", "warning");
            command.getReporter().error(new TestDiagnostic());
            try {
              command.getReporter().failIfPendingErrors();
            } catch (RuntimeException e) {
              throw InternalCompilationFailedExceptionUtils.createForTesting();
            }
          });
      fail("Failure expected");
    } catch (CompilationFailedException e) {
      // Expected.
    }

    DiagnosticsChecker.checkWarningsContains(
        "Test diagnostic",
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler,
                  "--map-diagnostics:com.android.tools.r8.TestDiagnostic",
                  "error",
                  "warning");
          command.getReporter().error(new TestDiagnostic());
        });

    DiagnosticsChecker.checkWarningsContains(
        "Test diagnostic",
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler, "--map-diagnostics:TestDiagnostic", "error", "warning");
          command.getReporter().error(new TestDiagnostic());
        });
  }

  @Test
  public void errorsToInfo() throws Exception {
    DiagnosticsChecker.checkInfosContains(
        "Error",
        handler -> {
          C command = parseWithRequiredArgs(handler, "--map-diagnostics", "error", "info");
          command.getReporter().error("Error");
        });

    try {
      DiagnosticsChecker.checkErrorsContains(
          "Test diagnostic",
          handler -> {
            C command = parseWithRequiredArgs(handler, "--map-diagnostics:a.b.C", "error", "info");
            command.getReporter().error(new TestDiagnostic());
            try {
              command.getReporter().failIfPendingErrors();
            } catch (RuntimeException e) {
              throw InternalCompilationFailedExceptionUtils.createForTesting();
            }
          });
      fail("Failure expected");
    } catch (CompilationFailedException e) {
      // Expected.
    }

    DiagnosticsChecker.checkInfosContains(
        "Test diagnostic",
        handler -> {
          C command =
              parseWithRequiredArgs(handler, "--map-diagnostics:TestDiagnostic", "error", "info");
          command.getReporter().error(new TestDiagnostic());
        });
  }

  @Test
  public void warningsToInfo() throws Exception {
    DiagnosticsChecker.checkInfosContains(
        "Warning",
        handler -> {
          C command = parseWithRequiredArgs(handler, "--map-diagnostics", "warning", "info");
          command.getReporter().warning("Warning");
        });

    DiagnosticsChecker.checkInfosContains(
        "Test diagnostic",
        handler -> {
          C command =
              parseWithRequiredArgs(handler, "--map-diagnostics:TestDiagnostic", "warning", "info");
          command.getReporter().warning(new TestDiagnostic());
        });
  }

  @Test
  public void warningsToError() {
    try {
      DiagnosticsChecker.checkErrorsContains(
          "Warning",
          handler -> {
            C command = parseWithRequiredArgs(handler, "--map-diagnostics", "warning", "error");
            command.getReporter().warning("Warning");
            try {
              command.getReporter().failIfPendingErrors();
            } catch (RuntimeException e) {
              throw InternalCompilationFailedExceptionUtils.createForTesting();
            }
          });
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }

    try {
      DiagnosticsChecker.checkErrorsContains(
          "Test diagnostic",
          handler -> {
            C command =
                parseWithRequiredArgs(
                    handler, "--map-diagnostics:TestDiagnostic", "warning", "error");
            command.getReporter().warning(new TestDiagnostic());
            try {
              command.getReporter().failIfPendingErrors();
            } catch (RuntimeException e) {
              throw InternalCompilationFailedExceptionUtils.createForTesting();
            }
          });
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void errorsToWarningsWarningsToInfos() throws Exception {
    DiagnosticsChecker.checkInfosContains(
        "Error",
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler,
                  "--map-diagnostics",
                  "error",
                  "warning",
                  "--map-diagnostics",
                  "warning",
                  "info");
          command.getReporter().error("Error");
        });

    DiagnosticsChecker.checkInfosContains(
        "Test diagnostic",
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler,
                  "--map-diagnostics:TestDiagnostic",
                  "error",
                  "warning",
                  "--map-diagnostics",
                  "warning",
                  "info");
          command.getReporter().error(new TestDiagnostic());
        });
  }

  @Test
  public void warningsToInfosErrorsToWarnings() throws Exception {
    DiagnosticsChecker.checkDiagnostics(
        diagnostics -> {
          assertEquals(0, diagnostics.errors.size());
          diagnostics.checkWarningsContains("Error");
          diagnostics.checkInfosContains("Warning");
        },
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler,
                  "--map-diagnostics",
                  "warning",
                  "info",
                  "--map-diagnostics",
                  "error",
                  "warning");
          command.getReporter().error("Error");
          command.getReporter().warning("Warning");
        });

    DiagnosticsChecker.checkDiagnostics(
        diagnostics -> {
          assertEquals(0, diagnostics.errors.size());
          diagnostics.checkWarningsContains("Test diagnostic");
          diagnostics.checkInfosContains("Test diagnostic");
        },
        handler -> {
          C command =
              parseWithRequiredArgs(
                  handler,
                  "--map-diagnostics:TestDiagnostic",
                  "warning",
                  "info",
                  "--map-diagnostics:TestDiagnostic",
                  "error",
                  "warning");
          command.getReporter().error(new TestDiagnostic());
          command.getReporter().warning(new TestDiagnostic());
        });
  }

  @Test
  public void artProfileFlagAbsentTest() throws Exception {
    assertTrue(parseWithRequiredArgs().getArtProfilesForRewriting().isEmpty());
  }

  @Test
  public void artProfileFlagPresentTest() throws Exception {
    // Create a simple profile.
    Path profile = temp.newFile("profile.txt").toPath();
    Path residualProfile = temp.newFile("profile-out.txt").toPath();
    String profileRuleFlags = "HSP";
    String profileRuleDescriptor = "Lfoo/bar/Baz;->qux()V";
    FileUtils.writeTextFile(profile, profileRuleFlags + profileRuleDescriptor);

    // Pass the profile on the command line.
    List<ArtProfileForRewriting> artProfilesForRewriting =
        parseWithRequiredArgs("--art-profile", profile.toString(), residualProfile.toString())
            .getArtProfilesForRewriting();
    assertEquals(1, artProfilesForRewriting.size());

    // Extract inputs.
    ArtProfileForRewriting artProfileForRewriting = artProfilesForRewriting.get(0);
    ArtProfileProvider artProfileProvider = artProfileForRewriting.getArtProfileProvider();
    ArtProfileConsumer residualArtProfileConsumer =
        artProfileForRewriting.getResidualArtProfileConsumer();
    InternalOptions options = new InternalOptions();

    // Build provided ART profile.
    ArtProfile.Builder artProfileBuilder =
        ArtProfile.builderForInitialArtProfile(artProfileProvider, options);
    artProfileProvider.getArtProfile(artProfileBuilder);
    ArtProfile artProfile = artProfileBuilder.build();

    // Verify we found the same rule.
    assertEquals(1, artProfile.size());
    IntBox count = new IntBox();
    artProfile.forEachRule(
        classRule -> fail(),
        methodRule -> {
          assertEquals(profileRuleDescriptor, methodRule.getMethod().toSmaliString());
          assertTrue(methodRule.getMethodRuleInfo().isHot());
          assertTrue(methodRule.getMethodRuleInfo().isStartup());
          assertTrue(methodRule.getMethodRuleInfo().isPostStartup());
          count.increment();
        });
    assertEquals(1, count.get());

    // Supply the rule back to the consumer.
    artProfile.supplyConsumer(residualArtProfileConsumer, options.reporter);
    assertEquals(
        ImmutableList.of(profileRuleFlags + profileRuleDescriptor),
        FileUtils.readAllLines(residualProfile));
  }

  @Test
  public void artProfileFlagMissingInputOutputParameterTest() {
    String expectedErrorContains = "Missing parameter for --art-profile.";
    try {
      DiagnosticsChecker.checkErrorsContains(
          expectedErrorContains, handler -> parseWithRequiredArgs(handler, "--art-profile"));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void artProfileFlagMissingOutputParameterTest() throws Exception {
    String expectedErrorContains = "Missing parameter for --art-profile.";
    Path profile = temp.newFile("profile.txt").toPath();
    FileUtils.writeTextFile(profile, "");
    try {
      DiagnosticsChecker.checkErrorsContains(
          expectedErrorContains,
          handler -> parseWithRequiredArgs(handler, "--art-profile", profile.toString()));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void startupProfileFlagAbsentTest() throws Exception {
    assertTrue(parseWithRequiredArgs().getStartupProfileProviders().isEmpty());
  }

  @Test
  public void startupProfileFlagPresentTest() throws Exception {
    // Create a simple profile.
    Path profile = temp.newFile("profile.txt").toPath();
    String profileRule = "Lfoo/bar/Baz;->qux()V";
    FileUtils.writeTextFile(profile, profileRule);

    // Pass the profile on the command line.
    List<StartupProfileProvider> startupProfileProviders;
    try {
      startupProfileProviders =
          parseWithRequiredArgs(
                  "--min-api",
                  Integer.toString(AndroidApiLevel.L.getLevel()),
                  "--startup-profile",
                  profile.toString())
              .getStartupProfileProviders();
    } catch (CompilationFailedException e) {
      assertTrue(isL8());
      return;
    }

    assertEquals(1, startupProfileProviders.size());

    // Construct the internal profile representation using the provider.
    InternalOptions options = new InternalOptions();
    MissingStartupProfileItemsDiagnostic.Builder missingStartupProfileItemsDiagnosticBuilder =
        MissingStartupProfileItemsDiagnostic.Builder.nop();
    StartupProfileProvider startupProfileProvider = startupProfileProviders.get(0);
    StartupProfile.Builder startupProfileBuilder =
        StartupProfile.builder(
            options, missingStartupProfileItemsDiagnosticBuilder, startupProfileProvider);
    startupProfileProvider.getStartupProfile(startupProfileBuilder);

    // Verify we found the same rule.
    StartupProfile startupProfile = startupProfileBuilder.build();
    Collection<StartupProfileRule> startupItems =
        ListUtils.newArrayList(consumer -> startupProfile.forEachRule(consumer::accept));
    assertEquals(1, startupItems.size());
    StartupProfileRule startupItem = startupItems.iterator().next();
    startupItem.accept(
        startupClass -> fail(),
        startupMethod -> assertEquals(profileRule, startupMethod.getReference().toSmaliString()));
  }

  @Test
  public void startupProfileFlagMissingParameterTest() {
    String expectedErrorContains =
        isL8() ? "Unknown option: --startup-profile" : "Missing parameter for --startup-profile.";
    try {
      DiagnosticsChecker.checkErrorsContains(
          expectedErrorContains, handler -> parseWithRequiredArgs(handler, "--startup-profile"));
      fail("Expected failure");
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  private String[] prepareArgs(String[] args) {
    String[] actualTestArgs;
    String[] additionalTestArgs = requiredArgsForTest();
    if (additionalTestArgs.length > 0) {
      actualTestArgs = new String[args.length + additionalTestArgs.length];
      System.arraycopy(additionalTestArgs, 0, actualTestArgs, 0, additionalTestArgs.length);
      System.arraycopy(args, 0, actualTestArgs, additionalTestArgs.length, args.length);
    } else {
      actualTestArgs = args;
    }
    return actualTestArgs;
  }

  private C parseWithRequiredArgs(String... args) throws CompilationFailedException {
    return parse(prepareArgs(args));
  }

  private C parseWithRequiredArgs(DiagnosticsHandler handler, String... args)
      throws CompilationFailedException {
    return parse(handler, prepareArgs(args));
  }

  protected InternalOptions getOptionsWithLoadedDesugaredLibraryConfiguration(
      C command, boolean libraryCompilation) throws IOException {
    InternalOptions options = command.getInternalOptions();
    LibraryDesugaringSpecification spec = LibraryDesugaringSpecification.JDK11;
    options.loadMachineDesugaredLibrarySpecification(
        Timing.empty(), spec.getAppForTesting(options, libraryCompilation));
    return options;
  }

  /**
   * Tests in this class are executed for all of D8, R8 and L8. When testing arguments this can add
   * additional required arguments to all tests
   */
  abstract String[] requiredArgsForTest();

  abstract C parse(String... args) throws CompilationFailedException;

  abstract C parse(DiagnosticsHandler handler, String... args) throws CompilationFailedException;
}
