// 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 org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import java.util.List;
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 SwitchEnumUnboxingTest extends EnumUnboxingTestBase {

  private static final Class<MyEnumFewCases> ENUM_CLASS = MyEnumFewCases.class;

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

  @Parameters(name = "{0} valueOpt: {1} keep: {2}")
  public static List<Object[]> data() {
    return enumUnboxingTestParameters();
  }

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

  @Test
  public void testEnumUnboxing() throws Exception {
    Class<Switch> classToTest = Switch.class;
    testForR8(parameters.getBackend())
        .addInnerClasses(SwitchEnumUnboxingTest.class)
        .addKeepMainRule(classToTest)
        .addKeepRules(enumKeepRules.getKeepRules())
        .addEnumUnboxingInspector(inspector -> inspector.assertUnboxed(ENUM_CLASS))
        .enableInliningAnnotations()
        .enableNeverClassInliningAnnotations()
        .noMinification() // For assertions.
        .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(this::assertSwitchPresentButSwitchMapRemoved)
        .run(parameters.getRuntime(), classToTest)
        .assertSuccess()
        .inspectStdOut(this::assertLines2By2Correct);
  }

  private void assertSwitchPresentButSwitchMapRemoved(CodeInspector i) {
    if (enumValueOptimization) {
      assertFalse(
          i.clazz("com.android.tools.r8.enumunboxing.SwitchEnumUnboxingTest$1").isPresent());
    }
    assertTrue(
        i.clazz(Switch.class)
            .uniqueMethodWithName("switchOnEnumManyCases")
            .streamInstructions()
            .anyMatch(InstructionSubject::isSwitch));
  }

  @NeverClassInline
  enum MyEnumFewCases {
    A,
    B,
    C;

    @NeverInline
    void print() {
      Switch.packagePrivatePrint();
    }
  }

  @NeverClassInline
  enum MyEnumManyCases {
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H,
    I;

    @NeverInline
    void print() {
      Switch.packagePrivatePrint();
    }
  }

  static class Switch {

    public static void main(String[] args) {
      System.out.println(switchOnEnumFewCases(MyEnumFewCases.A));
      System.out.println(0xC0FFEE);
      System.out.println(switchOnEnumFewCases(MyEnumFewCases.B));
      System.out.println(0xBABE);

      System.out.println(switchOnEnumManyCases(MyEnumManyCases.A));
      System.out.println(0xACE);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.B));
      System.out.println(0xBABE);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.C));
      System.out.println(0xC0FFEE);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.D));
      System.out.println(0xDEC0DE);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.E));
      System.out.println(0xEFFACE);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.F));
      System.out.println(0xF00D);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.G));
      System.out.println(0x0);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.H));
      System.out.println(0x1);
      System.out.println(switchOnEnumManyCases(MyEnumManyCases.I));
      System.out.println(0x2);

      MyEnumFewCases.A.print();
      MyEnumManyCases.A.print();
    }

    @NeverInline
    static void packagePrivatePrint() {
      System.out.println("package private dependency");
    }

    // This switch will be converted into branches.
    @NeverInline
    static int switchOnEnumFewCases(MyEnumFewCases e) {
      switch (e) {
        case A:
          return 0xC0FFEE;
        case B:
          return 0xBABE;
        default:
          return 0xDEADBEEF;
      }
    }

    // This switch will remain a switch.
    @NeverInline
    static int switchOnEnumManyCases(MyEnumManyCases e) {
      switch (e) {
        case A:
          return 0xACE;
        case B:
          return 0xBABE;
        case C:
          return 0xC0FFEE;
        case D:
          return 0xDEC0DE;
        case E:
          return 0xEFFACE;
        case F:
          return 0xF00D;
        case G:
          return 0x0;
        case H:
          return 0x1;
        case I:
          return 0x2;
        default:
          return 0xDEADBEEF;
      }
    }
  }
}
