// 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.Assume;
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())
        .build();
  }

  @Test
  public void testD8() throws Exception {
    Assume.assumeTrue(parameters.isDexRuntime());
    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().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) {
                  diagnostics
                      .assertOnlyErrors()
                      .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) {
                  diagnostics
                      .assertOnlyErrors()
                      .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));
          });
    }
  }
}
