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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.List;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class EnumToStringLibTest extends EnumUnboxingTestBase {

  private final TestParameters parameters;
  private final boolean enumValueOptimization;
  private final EnumKeepRules enumKeepRules;
  private final boolean enumUnboxing;

  @Parameterized.Parameters(name = "{0} valueOpt: {1} keep: {2} unbox: {3}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
        BooleanUtils.values(),
        getAllEnumKeepRules(),
        BooleanUtils.values());
  }

  public EnumToStringLibTest(
      TestParameters parameters,
      boolean enumValueOptimization,
      EnumKeepRules enumKeepRules,
      boolean enumUnboxing) {
    this.parameters = parameters;
    this.enumValueOptimization = enumValueOptimization;
    this.enumKeepRules = enumKeepRules;
    this.enumUnboxing = enumUnboxing;
  }

  @Test
  public void testToStringLib() throws Exception {
    Assume.assumeFalse(
        "The test rely on valueOf, so only studio or snap keep rules are valid.",
        enumKeepRules == EnumKeepRules.NONE);
    // Compile the lib cf to cf.
    R8TestCompileResult javaLibShrunk = compileLibrary();
    assertEnumFieldsMinified(javaLibShrunk.inspector());
    // Compile the program with the lib.
    R8TestCompileResult compile =
        testForR8(parameters.getBackend())
            .addProgramClasses(AlwaysCorrectProgram.class, AlwaysCorrectProgram2.class)
            .addProgramFiles(javaLibShrunk.writeToZip())
            .addKeepMainRule(AlwaysCorrectProgram.class)
            .addKeepMainRule(AlwaysCorrectProgram2.class)
            .addKeepRules(enumKeepRules.getKeepRules())
            .addKeepAttributeLineNumberTable()
            .addOptionsModification(
                options -> {
                  options.enableEnumUnboxing = enumUnboxing;
                  options.enableEnumValueOptimization = enumValueOptimization;
                  options.enableEnumSwitchMapRemoval = enumValueOptimization;
                })
            .setMinApi(parameters.getApiLevel())
            .compile();
      compile
          .run(parameters.getRuntime(), AlwaysCorrectProgram.class)
          .assertSuccessWithOutputLines("0", "1", "2", "0", "1", "2", "0", "1", "2");
      compile
          .run(parameters.getRuntime(), AlwaysCorrectProgram2.class)
          .assertSuccessWithOutputLines("0", "1", "2", "0", "1", "2");
  }

  private void assertEnumFieldsMinified(CodeInspector codeInspector) throws Exception {
    ClassSubject clazz = codeInspector.clazz(ToStringLib.LibEnum.class);
    assertThat(clazz, isPresent());
    for (String fieldName : new String[] {"COFFEE", "BEAN", "SUGAR"}) {
      assertThat(
          codeInspector.field(ToStringLib.LibEnum.class.getField(fieldName)),
          isPresentAndRenamed());
    }
  }

  private R8TestCompileResult compileLibrary() throws Exception {
    return testForR8(Backend.CF)
        .addProgramClasses(ToStringLib.class, ToStringLib.LibEnum.class)
        .addKeepRules(enumKeepRules.getKeepRules())
        .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
        .addKeepMethodRules(
            Reference.methodFromMethod(
                ToStringLib.class.getDeclaredMethod("lookupByName", String.class)),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("getCoffee")),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("getBean")),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("getSugar")),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("directCoffee")),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("directBean")),
            Reference.methodFromMethod(ToStringLib.class.getDeclaredMethod("directSugar")))
        .addKeepClassRules(ToStringLib.LibEnum.class)
        .setMinApi(parameters.getApiLevel())
        .compile();
  }

  // This class emulates a library with the three public methods getEnumXXX.
  public static class ToStringLib {

    // We pick names here that we assume won't be picked by the minifier (i.e., not a,b,c).
    public enum LibEnum {
      COFFEE,
      BEAN,
      SUGAR;
    }

    // If there is a keep rule on LibEnum fields, then ToStringLib.lookupByName("COFFEE")
    // should answer 0, else, the behavior of ToStringLib.lookupByName("COFFEE") is undefined.
    // ToStringLib.lookupByName(LibEnum.COFFEE.toString()) should always answer 0, no matter
    // what keep rules are on LibEnum.
    public static int lookupByName(String key) {
      if (key == null) {
        return -1;
      } else if (key.contains(LibEnum.COFFEE.name())) {
        return LibEnum.COFFEE.ordinal();
      } else if (key.contains(LibEnum.BEAN.name())) {
        return LibEnum.BEAN.ordinal();
      } else if (key.contains(LibEnum.SUGAR.name())) {
        return LibEnum.SUGAR.ordinal();
      } else {
        return -2;
      }
    }

    // The following method should always return 0, no matter what keep rules are on LibEnum.
    public static int directCoffee() {
      return LibEnum.valueOf(LibEnum.COFFEE.toString()).ordinal();
    }

    public static int directBean() {
      return LibEnum.valueOf(LibEnum.BEAN.toString()).ordinal();
    }

    public static int directSugar() {
      return LibEnum.valueOf(LibEnum.SUGAR.toString()).ordinal();
    }

    public static LibEnum getCoffee() {
      return LibEnum.COFFEE;
    }

    public static LibEnum getBean() {
      return LibEnum.BEAN;
    }

    public static LibEnum getSugar() {
      return LibEnum.SUGAR;
    }
  }

  // The next two classes emulate a program using the ToStringLib library.
  public static class AlwaysCorrectProgram {

    public static void main(String[] args) {
      System.out.println(ToStringLib.directCoffee());
      System.out.println(ToStringLib.directBean());
      System.out.println(ToStringLib.directSugar());
      System.out.println(ToStringLib.lookupByName(ToStringLib.getCoffee().toString()));
      System.out.println(ToStringLib.lookupByName(ToStringLib.getBean().toString()));
      System.out.println(ToStringLib.lookupByName(ToStringLib.getSugar().toString()));
      System.out.println(ToStringLib.LibEnum.valueOf(ToStringLib.getCoffee().toString()).ordinal());
      System.out.println(ToStringLib.LibEnum.valueOf(ToStringLib.getBean().toString()).ordinal());
      System.out.println(ToStringLib.LibEnum.valueOf(ToStringLib.getSugar().toString()).ordinal());
    }
  }

  public static class AlwaysCorrectProgram2 {

    public static void main(String[] args) {
      System.out.println(ToStringLib.lookupByName("COFFEE"));
      System.out.println(ToStringLib.lookupByName("BEAN"));
      System.out.println(ToStringLib.lookupByName("SUGAR"));
      System.out.println(ToStringLib.LibEnum.valueOf("COFFEE").ordinal());
      System.out.println(ToStringLib.LibEnum.valueOf("BEAN").ordinal());
      System.out.println(ToStringLib.LibEnum.valueOf("SUGAR").ordinal());
    }
  }
}
