// Copyright (c) 2018, 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.ir.optimize.reflection;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.ForceInline;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRunResult;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Collection;
import org.junit.Test;

class GetName0Class {
  static class InnerClass {
  }

  interface Itf {
    void foo();
  }

  @ForceInline
  static Itf createRunnable() {
    return new Itf() {
      @Override
      public void foo() {
        System.out.println("anonymous");
      }
    };
  }

  @ForceInline
  static GetName0Class factory() {
    return new GetName0Class() {
      @Override
      public String toString() {
        return "local";
      }
    };
  }
}

class GetName0Main {
  public static void main(String[] args) {
    {
      Class<?> test = GetName0Class.class;
      System.out.println(test.getName());
      // TODO(b/119426668): desugar Type#getTypeName
      // System.out.println(test.getTypeName());
      System.out.println(test.getCanonicalName());
      System.out.println(test.getSimpleName());
    }

    {
      Class<?> test = GetName0Class.InnerClass.class;
      System.out.println(test.getName());
      // TODO(b/119426668): desugar Type#getTypeName
      // System.out.println(test.getTypeName());
      System.out.println(test.getCanonicalName());
      System.out.println(test.getSimpleName());
    }

    {
      GetName0Class[] arr = new GetName0Class[1];
      Class<?> test = arr.getClass();
      System.out.println(test.getName());
      // TODO(b/119426668): desugar Type#getTypeName
      // System.out.println(test.getTypeName());
      System.out.println(test.getCanonicalName());
      System.out.println(test.getSimpleName());
    }

    {
      Class<?> test = GetName0Class.createRunnable().getClass();
      System.out.println(test.getName());
      // TODO(b/119426668): desugar Type#getTypeName
      // System.out.println(test.getTypeName());
      String name = test.getCanonicalName();
      System.out.println(name == null ? "-Returned-null-" : name);
      name = test.getSimpleName();
      System.out.println(name.isEmpty() ? "-Returned-empty-" : name);
    }

    {
      Class<?> test = GetName0Class.factory().getClass();
      System.out.println(test.getName());
      // TODO(b/119426668): desugar Type#getTypeName
      // System.out.println(test.getTypeName());
      String name = test.getCanonicalName();
      System.out.println(name == null ? "-Returned-null-" : name);
      name = test.getSimpleName();
      System.out.println(name.isEmpty() ? "-Returned-empty-" : name);
    }
  }
}

public class GetNameTest extends GetNameTestBase {
  private Collection<Path> classPaths;
  private static final String JAVA_OUTPUT = StringUtils.lines(
      // getName
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class",
      // getTypeName
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.GetName0Class",
      // getCanonicalName
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class",
      // getSimpleName
      "GetName0Class",
      // getName, inner
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class$InnerClass",
      // getTypeName, inner
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.GetName0Class$InnerClass",
      // getCanonicalName, inner
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class.InnerClass",
      // getSimpleName, inner
      "InnerClass",
      // getName, array
      "[Lcom.android.tools.r8.ir.optimize.reflection.GetName0Class;",
      // getTypeName, array
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.GetName0Class[]",
      // getCanonicalName, array
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class[]",
      // getSimpleName, array
      "GetName0Class[]",
      // getName, anonymous
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class$1",
      // getTypeName, anonymous
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.GetName0Class$1",
      // getCanonicalName, anonymous
      "-Returned-null-",
      // getSimpleName, anonymous
      "-Returned-empty-",
      // getName, local
      "com.android.tools.r8.ir.optimize.reflection.GetName0Class$2",
      // getTypeName, local
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.GetName0Class$2",
      // getCanonicalName, local
      "-Returned-null-",
      // getSimpleName, local
      "-Returned-empty-"
  );
  private static final String RENAMED_OUTPUT = StringUtils.lines(
      // getName
      "com.android.tools.r8.ir.optimize.reflection.c",
      // getTypeName
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.c",
      // getCanonicalName
      "com.android.tools.r8.ir.optimize.reflection.c",
      // getSimpleName
      "c",
      // getName, inner
      "com.android.tools.r8.ir.optimize.reflection.c$a",
      // getTypeName, inner
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.c$a",
      // getCanonicalName, inner
      "com.android.tools.r8.ir.optimize.reflection.c.a",
      // getSimpleName, inner
      "a",
      // getName, array
      "[Lcom.android.tools.r8.ir.optimize.reflection.c;",
      // getTypeName, array
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.c[]",
      // getCanonicalName, array
      "com.android.tools.r8.ir.optimize.reflection.c[]",
      // getSimpleName, array
      "c[]",
      // getName, anonymous
      "com.android.tools.r8.ir.optimize.reflection.a",
      // getTypeName, anonymous
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.a",
      // getCanonicalName, anonymous
      "-Returned-null-",
      // getSimpleName, anonymous
      "-Returned-empty-",
      // getName, local
      "com.android.tools.r8.ir.optimize.reflection.b",
      // getTypeName, local
      // TODO(b/119426668): desugar Type#getTypeName
      // "com.android.tools.r8.ir.optimize.reflection.b,
      // getCanonicalName, local
      "-Returned-null-",
      // getSimpleName, local
      "-Returned-empty-"
  );
  private static final Class<?> MAIN = GetName0Main.class;

  public GetNameTest(TestParameters parameters, boolean enableMinification) throws Exception {
    super(parameters, enableMinification);

    ImmutableList.Builder<Path> builder = ImmutableList.builder();
    builder.addAll(ToolHelper.getClassFilesForTestDirectory(
        ToolHelper.getPackageDirectoryForTestPackage(MAIN.getPackage()),
        path -> path.getFileName().toString().startsWith("GetName0")));
    builder.add(ToolHelper.getClassFileForTestClass(ForceInline.class));
    classPaths = builder.build();
  }

  @Test
  public void testJVMOutput() throws Exception {
    assumeTrue(
        "Only run JVM reference on CF runtimes",
        parameters.isCfRuntime() && !enableMinification);
    testForJvm()
        .addTestClasspath()
        .run(parameters.getRuntime(), MAIN)
        .assertSuccessWithOutput(JAVA_OUTPUT);
  }

  private void test(TestRunResult result, int expectedCount) throws Exception {
    CodeInspector codeInspector = result.inspector();
    ClassSubject mainClass = codeInspector.clazz(MAIN);
    MethodSubject mainMethod = mainClass.mainMethod();
    assertThat(mainMethod, isPresent());
    long count = countGetName(mainMethod);
    assertEquals(expectedCount, count);
  }

  @Test
  public void testD8() throws Exception {
    assumeTrue("Only run D8 for Dex backend)", parameters.isDexRuntime() && !enableMinification);

    D8TestRunResult result =
        testForD8()
            .debug()
            .addProgramFiles(classPaths)
            .setMinApi(parameters.getRuntime())
            .addOptionsModification(this::configure)
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    test(result, 15);

    result =
        testForD8()
            .release()
            .addProgramFiles(classPaths)
            .setMinApi(parameters.getRuntime())
            .addOptionsModification(this::configure)
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    // getClass() -> const-class is not available in D8.
    test(result, 11);
  }

  @Test
  public void testR8_pinning() throws Exception {
    // Pinning the test class.
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(classPaths)
            .addKeepMainRule(MAIN)
            .addKeepRules("-keep class **.GetName0*")
            .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
            .addKeepRules("-printmapping " + createNewMappingPath().toAbsolutePath().toString())
            .minification(enableMinification)
            .setMinApi(parameters.getRuntime())
            .addOptionsModification(this::configure)
            .run(parameters.getRuntime(), MAIN)
            .assertSuccessWithOutput(JAVA_OUTPUT);
    test(result, 2);
  }

  @Test
  public void testR8_shallow_pinning() throws Exception {
    // Shallow pinning the test class.
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(classPaths)
            .addKeepMainRule(MAIN)
            .addKeepRules("-keep,allowobfuscation class **.GetName0*")
            .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
            .addKeepRules("-printmapping " + createNewMappingPath().toAbsolutePath().toString())
            .minification(enableMinification)
            .setMinApi(parameters.getRuntime())
            .addOptionsModification(this::configure)
            .run(parameters.getRuntime(), MAIN);
    if (enableMinification) {
      result.assertSuccessWithOutput(RENAMED_OUTPUT);
    } else {
      result.assertSuccessWithOutput(JAVA_OUTPUT);
    }
    test(result, 2);
  }

}
