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

import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final AndroidApiLevel nativeMultiDexLevel = AndroidApiLevel.L;

  static final String EXPECTED = StringUtils.lines("AB");

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters()
        .withAllRuntimes()
        .withApiLevelsEndingAtExcluding(nativeMultiDexLevel)
        .build();
  }

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

  @Test
  public void testFinal() throws Exception {
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addTestClasspath()
          .run(parameters.getRuntime(), TestClass.class)
          .assertSuccessWithOutput(EXPECTED);
    } else {
      D8TestCompileResult compileResult =
          testForD8()
              .addInnerClasses(MainDexWithSynthesizedClassesTest.class)
              .addMainDexListClasses(TestClass.class, A.class)
              .setMinApiThreshold(parameters.getApiLevel())
              .compile();
      checkCompilationResult(compileResult);
    }
  }

  @Test
  public void testIntermediate() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    D8TestCompileResult intermediateResult =
        testForD8()
            .addInnerClasses(MainDexWithSynthesizedClassesTest.class)
            .setMinApiThreshold(parameters.getApiLevel())
            .setIntermediate(true)
            .compile();
    D8TestCompileResult compileResult =
        testForD8()
            .addProgramFiles(intermediateResult.writeToZip())
            .addMainDexListClasses(TestClass.class, A.class)
            .setMinApiThreshold(parameters.getApiLevel())
            .compile();
    checkCompilationResult(compileResult);
  }

  private void checkCompilationResult(D8TestCompileResult compileResult) throws Exception {
    if (parameters.getRuntime().asDex().getMinApiLevel().getLevel()
        < nativeMultiDexLevel.getLevel()) {
      compileResult
          .runDex2Oat(parameters.getRuntime().asDex().getVm())
          .assertNoVerificationErrors();
    } else {
      compileResult.run(parameters.getRuntime(), TestClass.class).assertSuccessWithOutput(EXPECTED);
    }
    Path out = temp.newFolder().toPath();
    compileResult.apply(b -> b.app.writeToDirectory(out, OutputMode.DexIndexed));
    Path classes = out.resolve("classes.dex");
    Path classes2 = out.resolve("classes2.dex");
    assertTrue(Files.exists(classes));
    assertTrue(Files.exists(classes2));
    checkContainsLambdaClasses(new CodeInspector(classes), A.class);
    checkContainsLambdaClasses(new CodeInspector(classes2), B.class);
  }

  private void checkContainsLambdaClasses(CodeInspector inspector, Class<?> lambdaHolder) {
    assertTrue(
        inspector.allClasses().stream()
            .anyMatch(
                clazz ->
                    clazz.getOriginalName().contains(LambdaRewriter.LAMBDA_CLASS_NAME_PREFIX)
                        && clazz
                            .getOriginalName()
                            .contains("$" + lambdaHolder.getSimpleName() + "$")));
  }

  static class TestClass {
    public static void main(String[] args) {
      System.out.println(new A().foo().get());
    }
  }

  interface Getter {
    String get();
  }

  static class A {
    Getter foo() {
      return () -> "A" + new B().foo().get();
    }
  }

  static class B {
    Getter foo() {
      return () -> "B";
    }
  }
}
