// Copyright (c) 2017, 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.assertTrue;

import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.OffOrAuto;
import java.nio.file.Path;
import java.util.function.UnaryOperator;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;

public class D8RunExamplesAndroidOTest extends RunExamplesAndroidOTest<D8Command.Builder> {

  class D8TestRunner extends TestRunner<D8TestRunner> {

    D8TestRunner(String testName, String packageName, String mainClass) {
      super(testName, packageName, mainClass);
    }

    @Override
    D8TestRunner withMinApiLevel(AndroidApiLevel minApiLevel) {
      return withBuilderTransformation(builder -> builder.setMinApiLevel(minApiLevel.getLevel()));
    }

    D8TestRunner withClasspath(Path... classpath) {
      return withBuilderTransformation(b -> b.addClasspathFiles(classpath));
    }

    @Override
    void build(Path inputFile, Path out, OutputMode mode) throws CompilationFailedException {
      D8Command.Builder builder = D8Command.builder().setOutput(out, mode);
      for (UnaryOperator<D8Command.Builder> transformation : builderTransformations) {
        builder = transformation.apply(builder);
      }
      builder.addLibraryFiles(
          ToolHelper.getAndroidJar(
              androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
      builder.addProgramFiles(inputFile);
      ToolHelper.runD8(builder, this::combinedOptionConsumer);
    }

    D8TestRunner withIntermediate(boolean intermediate) {
      return withBuilderTransformation(builder -> builder.setIntermediate(intermediate));
    }

    @Override
    D8TestRunner self() {
      return this;
    }
  }

  @Test
  public void testDefaultInInterfaceWithoutDesugaring() throws Throwable {
    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("testDefaultInInterfaceWithoutDesugaring", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Off)
            .withMinApiLevel(AndroidApiLevel.K);
    try  {
      lib1.build();

      // compilation should have failed on CompilationError since A is declaring a default method.
      Assert.fail();
    } catch (CompilationFailedException e) {
      // Expected.
    }
  }

  @Test
  public void testMissingInterfaceDesugared() throws Throwable {
    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(AndroidApiLevel.K);
    lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(AndroidApiLevel.K);
    lib2.build();

    // test: class ImplementMethodsWithDefault implements A, B {} should get its foo implementation
    // from B.
    // test is compiled with incomplete classpath: lib2 is missing so ImplementMethodsWithDefault is
    // missing one of it interfaces.
    D8TestRunner test =
        test("desugaringwithmissingclasstest1", "desugaringwithmissingclasstest1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(AndroidApiLevel.K);
    test.build();

    // TODO check compilation warnings are correctly reported
    // B is missing so compiled code makes no sense, no need to test execution.
  }

  @Test
  public void testMissingInterfaceDesugared2AndroidK() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.K;

    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib2Dex = lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B should get its foo
    // implementation from B.
    // test is compiled with incomplete classpath: lib2 and lib3 are missing so
    // ImplementMethodsWithDefault is missing all its hierarchy.
    D8TestRunner test =
        test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();
    // TODO check compilation warnings are correctly reported

    // Missing interface B is causing the wrong code to be executed.
    if (!ToolHelper.artSupported() && !ToolHelper.compareAgaintsGoldenFiles()) {
      return;
    }
    if (ToolHelper.artSupported() && !ToolHelper.compareAgaintsGoldenFiles()) {
      thrown.expect(AssertionError.class);
    }
    execute(
        "testMissingInterfaceDesugared2AndroidK",
        "desugaringwithmissingclasstest2.Main",
        new Path[] {
            lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});

  }

  @Test
  public void testMissingInterfaceDesugared2AndroidO() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.O;
    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib2Dex = lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B should get its foo
    // implementation from B.
    // test is compiled with incomplete classpath: lib2 and lib3 are missing so
    // ImplementMethodsWithDefault is missing all its hierarchy.
    D8TestRunner test =
        test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();
    execute(
        "testMissingInterfaceDesugared2AndroidO",
        "desugaringwithmissingclasstest2.Main",
        new Path[] {
          lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
  }

  @Test
  public void testCallToMissingSuperInterfaceDesugaredAndroidK() throws Throwable {

    AndroidApiLevel minApi = AndroidApiLevel.K;
    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib2Dex = lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B
    // { String getB() { return B.super.foo(); }
    // Should be able to call implementation from B.
    // test is compiled with incomplete classpath: lib2, i.e. B definition, is missing.
    D8TestRunner test =
        test("desugaringwithmissingclasstest3", "desugaringwithmissingclasstest3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar(), lib3.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();
    // TODO check compilation warnings are correctly reported

    Assume.assumeTrue(ToolHelper.artSupported() || ToolHelper.compareAgaintsGoldenFiles());

    // Missing interface B is causing the wrong method to be executed.
    if (ToolHelper.artSupported() && !ToolHelper.compareAgaintsGoldenFiles()) {
      thrown.expect(AssertionError.class);
    }
    execute(
        "testCallToMissingSuperInterfaceDesugaredAndroidK",
        "desugaringwithmissingclasstest3.Main",
        new Path[] {
            lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});

  }

  @Test
  public void testCallToMissingSuperInterfaceDesugaredAndroidO() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.O;
    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib2Dex = lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B
    // { String getB() { return B.super.foo(); }
    // Should be able to call implementation from B.
    // test is compiled with incomplete classpath: lib2, i.e. B definition, is missing.
    D8TestRunner test =
        test("desugaringwithmissingclasstest3", "desugaringwithmissingclasstest3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar(), lib3.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();
    execute(
        "testCallToMissingSuperInterfaceDesugaredAndroidO",
        "desugaringwithmissingclasstest3.Main",
        new Path[] {
          lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
  }

  @Test
  public void testMissingSuperDesugaredAndroidK() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.K;

    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B should get its foo
    // implementation from B.
    // test is compiled with incomplete classpath: lib3 is missing so
    // ImplementMethodsWithDefault is missing its super class.
    D8TestRunner test =
        test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withClasspath(lib2.getInputJar())
            .withMinApiLevel(minApi);
    try {
      test.build();
      Assert.fail("Expected build to fail with CompilationFailedException");
    } catch (CompilationFailedException e) {
      String message = e.getCause().getMessage();
      assertTrue(message.contains("desugaringwithmissingclasstest2.ImplementMethodsWithDefault"));
      assertTrue(message.contains("desugaringwithmissingclasslib3.C"));
    }
  }

  @Test
  public void testMissingSuperDesugaredAndroidO() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.O;

    // lib1: interface A { default String foo() { return "A"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib2: interface B extends A { default String foo() { return "B"; } }
    // lib2 is compiled with full classpath
    D8TestRunner lib2 =
        test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib2Dex = lib2.build();

    // lib3:  class C implements A {}
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class ImplementMethodsWithDefault extends C implements B should get its foo
    // implementation from B.
    // test is compiled with incomplete classpath: lib3 is missing so
    // ImplementMethodsWithDefault is missing its super class.
    D8TestRunner test =
        test("desugaringwithmissingclasstest2", "desugaringwithmissingclasstest2", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withClasspath(lib2.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();

    execute(
        "testMissingSuperDesugaredAndroidO",
        "desugaringwithmissingclasstest2.Main",
        new Path[] {
          lib1.getInputJar(), lib2.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib2Dex, lib3Dex, testDex});
  }

  @Test
  public void testMissingSuperDesugaredWithLibInterfaceAndroidK() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.K;

    // Reference case: there's nothing to do, we should not complain.
    // Class MissingSuperImplementIterator extends C implements Iterator should not require
    // desugaring because Iterator has no default method at this API level.
    // The test is compiled with incomplete classpath: lib3 is missing so
    // MissingSuperImplementIterator is missing its super class.
    test("desugaringwithmissingclasstest6", "desugaringwithmissingclasstest6", "N/A")
        .withInterfaceMethodDesugaring(OffOrAuto.Auto)
        .withAndroidJar(AndroidApiLevel.K)
        .withMinApiLevel(minApi)
        .build();

    // More litigious case, D8 needs to detect that the default method is part of bootclasspath.
    // Class MissingSuperImplementIterator extends C implements Iterator should not require
    // desugaring of Iterator default method because it is part of the Android API and thus is
    // declaring the default method only when default methods are supported by the runtime.
    // test is compiled with incomplete classpath: lib3 is missing so
    // MissingSuperImplementIterator is missing its super class.
    test("desugaringwithmissingclasstest6", "desugaringwithmissingclasstest6", "N/A")
        .withInterfaceMethodDesugaring(OffOrAuto.Auto)
        .withAndroidJar(AndroidApiLevel.N)
        .withMinApiLevel(minApi)
        .build();
  }

  @Test
  public void testMissingSuperDesugaredWithProgramCrossImplementationAndroidK() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.K;

    // lib1: interface A { default String foo() { return "A"; } }
    //       interface A2 { default String foo2() { return "A2"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib3: class C { /* content irrelevant }
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // test: class C2 extends C { public String foo2() { return "C2"; } }
    //       class ImplementMethodsWithDefault extends C2 implements A, A2 {
    //            public String foo() { return "ImplementMethodsWithDefault"; }
    //       }
    // test is compiled with incomplete classpath: lib3 is missing so
    // C2 is missing its super class. But desugaring should be OK since all
    // interface methods are explicitly defined in program classes of the hierarchy.
    D8TestRunner test =
        test("desugaringwithmissingclasstest4", "desugaringwithmissingclasstest4", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();

    execute(
        "testMissingSuperDesugaredAndroidKWithCrossImplementation",
        "desugaringwithmissingclasstest4.Main",
        new Path[] {
          lib1.getInputJar(), lib3.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib3Dex, testDex});

  }

  @Test
  public void testMissingSuperDesugaredWithClasspathCrossImplementationAndroidK() throws Throwable {
    AndroidApiLevel minApi = AndroidApiLevel.K;

    // lib1: interface A { default String foo() { return "A"; } }
    //       interface A2 { default String foo2() { return "A2"; } }
    D8TestRunner lib1 =
        test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withMinApiLevel(minApi);
    Path lib1Dex = lib1.build();

    // lib3: class C { /* content irrelevant }
    // lib3 is compiled with full classpath
    D8TestRunner lib3 =
        test("desugaringwithmissingclasslib3", "desugaringwithmissingclasslib3", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar())
            .withMinApiLevel(minApi);
    Path lib3Dex = lib3.build();

    // lib4: class C2 extends C { public String foo2() { return "C2"; } }
    // lib4 is compiled with full classpath
    D8TestRunner lib4 =
        test("desugaringwithmissingclasslib4", "desugaringwithmissingclasslib4", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar(), lib3.getInputJar())
            .withMinApiLevel(minApi);
    Path lib4Dex = lib4.build();

    // test: class ImplementMethodsWithDefault extends C2 implements A, A2 {
    //            public String foo() { return "ImplementMethodsWithDefault"; }
    //       }
    // test is compiled with incomplete classpath: lib3 is missing so
    // C2 is missing its super class. But desugaring should be OK since all
    // interface methods are explicitly defined in program classes of the hierarchy.
    D8TestRunner test =
        test("desugaringwithmissingclasstest4", "desugaringwithmissingclasstest4", "N/A")
            .withInterfaceMethodDesugaring(OffOrAuto.Auto)
            .withClasspath(lib1.getInputJar(), lib4.getInputJar())
            .withMinApiLevel(minApi);
    Path testDex = test.build();

    execute(
        "testMissingSuperDesugaredAndroidKWithCrossImplementation",
        "desugaringwithmissingclasstest4.Main",
        new Path[] {
          lib1.getInputJar(), lib3.getInputJar(), lib4.getInputJar(), test.getInputJar()
        },
        new Path[] {lib1Dex, lib3Dex, lib4Dex, testDex});

  }

  @Override
  D8TestRunner test(String testName, String packageName, String mainClass) {
    return new D8TestRunner(testName, packageName, mainClass);
  }
}
