// Copyright (c) 2019, 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.desugar.nestaccesscontrol;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.CLASSES_PATH;
import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.CLASS_NAMES;
import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.core.StringContains.containsString;
import static org.hamcrest.core.StringEndsWith.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.Jdk9TestUtils;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestCompileResult;
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.diagnostic.internal.MissingDefinitionsDiagnosticImpl;
import com.android.tools.r8.errors.IncompleteNestNestDesugarDiagnosic;
import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
import com.android.tools.r8.errors.MissingNestHostNestDesugarDiagnostic;
import com.android.tools.r8.references.Reference;
import java.nio.file.Path;
import java.util.List;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class NestCompilationExceptionTest extends TestBase {

  public NestCompilationExceptionTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters()
        .withCfRuntimesStartingFromIncluding(CfVm.JDK11)
        .withDexRuntime(DexVm.Version.first())
        .withDexRuntime(DexVm.Version.last())
        .withApiLevelsStartingAtIncluding(apiLevelWithInvokeCustomSupport())
        .enableApiLevelsForCf()
        .build();
  }

  @Test
  public void testD8() throws Exception {
    testMissingNestHostError(true);
    testIncompleteNestError(true);
  }

  @Test
  public void testWarningR8() throws Exception {
    testIncompleteNestWarning(false, parameters.isDexRuntime());
    testMissingNestHostWarning(false, parameters.isDexRuntime());
  }

  @Test
  public void testErrorR8() {
    testMissingNestHostError(false);
    testIncompleteNestError(false);
  }

  private TestCompilerBuilder<?, ?, ?, ?, ?> compileOnlyClassesMatching(
      Matcher<String> matcher,
      boolean d8,
      boolean allowDiagnosticWarningMessages,
      boolean ignoreMissingClasses) {
    List<Path> matchingClasses =
        CLASS_NAMES.stream()
            .filter(matcher::matches)
            .map(name -> CLASSES_PATH.resolve(name + CLASS_EXTENSION))
            .collect(toList());
    if (d8) {
      return testForD8(parameters.getBackend())
          .setMinApi(parameters.getApiLevel())
          .addProgramFiles(matchingClasses);
    } else {
      return testForR8(parameters.getBackend())
          .noTreeShaking()
          .noMinification()
          .addKeepAllAttributes()
          .setMinApi(parameters.getApiLevel())
          .addProgramFiles(matchingClasses)
          .applyIf(parameters.isCfRuntime(), Jdk9TestUtils.addJdk9LibraryFiles(temp))
          .addIgnoreWarnings(ignoreMissingClasses)
          .allowDiagnosticWarningMessages(allowDiagnosticWarningMessages);
    }
  }

  private void testMissingNestHostError(boolean d8) {
    try {
      Matcher<String> innerClassMatcher =
          containsString("BasicNestHostWithInnerClassMethods$BasicNestedClass");
      compileOnlyClassesMatching(innerClassMatcher, d8, false, false)
          .compileWithExpectedDiagnostics(
              diagnostics -> {
                if (d8) {
                  if (parameters.getBackend().isDex()) {
                    diagnostics.assertOnlyErrors();
                  }
                  diagnostics.assertErrorsMatch(
                      diagnosticType(MissingNestHostNestDesugarDiagnostic.class));

                  MissingNestHostNestDesugarDiagnostic diagnostic =
                      (MissingNestHostNestDesugarDiagnostic) diagnostics.getErrors().get(0);
                  assertEquals(
                      "Class BasicNestHostWithInnerClassMethods$BasicNestedClass requires its nest "
                          + "host BasicNestHostWithInnerClassMethods to be on program or class "
                          + "path.",
                      diagnostic.getDiagnosticMessage());
                } else {
                  diagnostics
                      .assertOnlyErrors()
                      .inspectErrors(
                          diagnostic ->
                              diagnostic
                                  .assertIsMissingDefinitionsDiagnostic()
                                  .assertIsMissingClass(
                                      Reference.classFromTypeName(
                                          "nesthostexample.BasicNestHostWithInnerClassMethods"))
                                  .assertNumberOfMissingClasses(1));
                }
              });
    } catch (CompilationFailedException e) {
      // Expected failure.
      return;
    }
    fail("Should have raised an exception for missing nest host");
  }

  private void testIncompleteNestError(boolean d8) {
    try {
      Matcher<String> innerClassMatcher = endsWith("BasicNestHostWithInnerClassMethods");
      compileOnlyClassesMatching(innerClassMatcher, d8, false, false)
          .compileWithExpectedDiagnostics(
              diagnostics -> {
                if (d8) {
                  if (parameters.getBackend().isDex()) {
                    diagnostics.assertOnlyErrors();
                  }
                  diagnostics.assertErrorsMatch(
                      diagnosticType(IncompleteNestNestDesugarDiagnosic.class));

                  IncompleteNestNestDesugarDiagnosic diagnostic =
                      (IncompleteNestNestDesugarDiagnosic) diagnostics.getErrors().get(0);
                  assertEquals(
                      "Compilation of classes nesthostexample.BasicNestHostWithInnerClassMethods "
                          + "requires its nest mates "
                          + "nesthostexample.BasicNestHostWithInnerClassMethods$BasicNestedClass "
                          + "(unavailable) to be on program or class path.",
                      diagnostic.getDiagnosticMessage());
                } else {
                  diagnostics
                      .assertOnlyErrors()
                      .inspectErrors(
                          diagnostic ->
                              diagnostic
                                  .assertIsMissingDefinitionsDiagnostic()
                                  .assertIsMissingClass(
                                      Reference.classFromTypeName(
                                          "nesthostexample.BasicNestHostWithInnerClassMethods$BasicNestedClass"))
                                  .assertNumberOfMissingClasses(1));
                }
              });
    } catch (Exception e) {
      // Expected failure.
      return;
    }
    fail("Should have raised an exception for incomplete nest");
  }

  private void testMissingNestHostWarning(boolean d8, boolean desugarWarning) throws Exception {
    Matcher<String> innerClassMatcher =
        containsString("BasicNestHostWithInnerClassMethods$BasicNestedClass");
    TestCompileResult<?, ?> compileResult =
        compileOnlyClassesMatching(innerClassMatcher, d8, !d8, true).compile();
    assertTrue(compileResult.getDiagnosticMessages().getWarnings().size() >= 1);
    if (d8 && desugarWarning) {
      assertTrue(
          compileResult.getDiagnosticMessages().getWarnings().stream()
              .anyMatch(warn -> warn instanceof MissingNestHostNestDesugarDiagnostic));
    }
    if (!d8) {
      // R8 should raise extra warning when cleaning the nest.
      compileResult.inspectDiagnosticMessages(
          diagnostics -> {
            diagnostics.assertOnlyWarnings();
            if (parameters.isCfRuntime() || parameters.canUseDefaultAndStaticInterfaceMethods()) {
              diagnostics.assertWarningsMatch(
                  diagnosticType(MissingDefinitionsDiagnosticImpl.class));
            } else {
              diagnostics.assertWarningsMatch(
                  diagnosticType(MissingDefinitionsDiagnosticImpl.class),
                  diagnosticType(InterfaceDesugarMissingTypeDiagnostic.class));
            }
            diagnostics.inspectWarning(
                0,
                diagnostic ->
                    diagnostic
                        .assertIsMissingDefinitionsDiagnostic()
                        .assertIsMissingClass(
                            Reference.classFromTypeName(
                                "nesthostexample.BasicNestHostWithInnerClassMethods"))
                        .assertNumberOfMissingClasses(1));
          });
    }
  }

  private void testIncompleteNestWarning(boolean d8, boolean desugarWarning) throws Exception {
    Matcher<String> innerClassMatcher = endsWith("BasicNestHostWithInnerClassMethods");
    TestCompileResult<?, ?> compileResult =
        compileOnlyClassesMatching(innerClassMatcher, d8, !d8, true).compile();
    assertTrue(compileResult.getDiagnosticMessages().getWarnings().size() >= 1);
    if (d8 && desugarWarning) {
      assertTrue(
          compileResult.getDiagnosticMessages().getWarnings().stream()
              .anyMatch(warn -> warn instanceof IncompleteNestNestDesugarDiagnosic));
    }
    if (!d8) {
      // R8 should raise extra warning when cleaning the nest.
      compileResult.inspectDiagnosticMessages(
          diagnostics -> {
            diagnostics.assertOnlyWarnings();
            if (parameters.isCfRuntime() || parameters.canUseDefaultAndStaticInterfaceMethods()) {
              diagnostics.assertWarningsMatch(
                  diagnosticType(MissingDefinitionsDiagnosticImpl.class));
            } else {
              diagnostics.assertWarningsMatch(
                  diagnosticType(MissingDefinitionsDiagnosticImpl.class),
                  diagnosticType(InterfaceDesugarMissingTypeDiagnostic.class));
            }
            diagnostics.inspectWarning(
                0,
                diagnostic ->
                    diagnostic
                        .assertIsMissingDefinitionsDiagnostic()
                        .assertIsMissingClass(
                            Reference.classFromTypeName(
                                "nesthostexample.BasicNestHostWithInnerClassMethods$BasicNestedClass"))
                        .assertNumberOfMissingClasses(1));
          });
    }
  }
}
