// 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.fail;

import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.AppForSpecConversion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import org.junit.Test;

public abstract class CommandTestBase<C extends BaseCompilerCommand> extends TestBase {
  private void mapDiagnosticsMissingArguments(String... args) throws Exception {
    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) throws Exception {
    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() throws Exception {
    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 new CompilationFailedException();
            }
          });
      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 new CompilationFailedException();
            }
          });
      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() throws Exception {
    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 new CompilationFailedException();
            }
          });
      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 new CompilationFailedException();
            }
          });
      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());
        });
  }

  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();
    options.loadMachineDesugaredLibrarySpecification(
        Timing.empty(),
        AppForSpecConversion.readAppForTesting(
            libraryCompilation ? ToolHelper.getDesugarJDKLibs() : null,
            ToolHelper.getAndroidJar(AndroidApiLevel.R),
            options,
            libraryCompilation,
            Timing.empty()));
    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;
}
