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

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.enumunboxing.FailingEnumUnboxingAnalysisTest.EnumInstanceFieldMain.EnumInstanceField;
import com.android.tools.r8.enumunboxing.FailingEnumUnboxingAnalysisTest.EnumInterfaceMain.EnumInterface;
import com.android.tools.r8.enumunboxing.FailingEnumUnboxingAnalysisTest.EnumStaticFieldMain.EnumStaticField;
import com.android.tools.r8.enumunboxing.FailingEnumUnboxingAnalysisTest.EnumStaticMethodMain.EnumStaticMethod;
import com.android.tools.r8.enumunboxing.FailingEnumUnboxingAnalysisTest.EnumVirtualMethodMain.EnumVirtualMethod;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
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 FailingEnumUnboxingAnalysisTest extends EnumUnboxingTestBase {

  private static final Class<?>[] FAILURES = {
    EnumInterface.class,
    EnumStaticField.class,
    EnumInstanceField.class,
    EnumStaticMethod.class,
    EnumVirtualMethod.class
  };

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return enumUnboxingTestParameters();
  }

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

  @Test
  public void testEnumUnboxingFailure() throws Exception {
    R8FullTestBuilder r8FullTestBuilder =
        testForR8(parameters.getBackend()).addInnerClasses(FailingEnumUnboxingAnalysisTest.class);
    for (Class<?> failure : FAILURES) {
      r8FullTestBuilder.addKeepMainRule(failure.getEnclosingClass());
    }
    R8TestCompileResult compile =
        r8FullTestBuilder
            .noTreeShaking() // Disabled to avoid merging Itf into EnumInterface.
            .enableInliningAnnotations()
            .addKeepRules(KEEP_ENUM)
            .addOptionsModification(this::enableEnumOptions)
            .allowDiagnosticInfoMessages()
            .setMinApi(parameters.getApiLevel())
            .compile()
            .inspect(this::assertEnumsAsExpected);
    for (Class<?> failure : FAILURES) {
      R8TestRunResult run =
          compile
              .inspectDiagnosticMessages(
                  m -> assertEnumIsBoxed(failure, failure.getSimpleName(), m))
              .run(parameters.getRuntime(), failure.getEnclosingClass())
              .assertSuccess();
      assertLines2By2Correct(run.getStdOut());
    }
  }

  private void assertEnumsAsExpected(CodeInspector inspector) {
    assertEquals(1, inspector.clazz(EnumInterface.class).getDexClass().interfaces.size());

    assertTrue(inspector.clazz(EnumStaticField.class).uniqueFieldWithName("X").isPresent());
    assertTrue(inspector.clazz(EnumInstanceField.class).uniqueFieldWithName("a").isPresent());

    assertEquals(5, inspector.clazz(EnumStaticMethod.class).getDexClass().directMethods().size());
    assertEquals(1, inspector.clazz(EnumVirtualMethod.class).virtualMethods().size());
  }

  static class EnumInterfaceMain {

    public static void main(String[] args) {
      System.out.println(EnumInterface.A.ordinal());
      System.out.println(0);
    }

    enum EnumInterface implements Itf {
      A,
      B,
      C
    }

    interface Itf {

      default int ordinal() {
        return -1;
      }
    }
  }

  static class EnumStaticFieldMain {

    public static void main(String[] args) {
      System.out.println(EnumStaticField.A.ordinal());
      System.out.println(0);
      System.out.println(EnumStaticField.X.ordinal());
      System.out.println(0);
    }

    enum EnumStaticField {
      A,
      B,
      C;
      static EnumStaticField X = A;
    }
  }

  static class EnumInstanceFieldMain {

    enum EnumInstanceField {
      A(10),
      B(20),
      C(30);
      private int a;

      EnumInstanceField(int i) {
        this.a = i;
      }
    }

    public static void main(String[] args) {
      System.out.println(EnumInstanceField.A.ordinal());
      System.out.println(0);
      System.out.println(EnumInstanceField.A.a);
      System.out.println(10);
    }
  }

  static class EnumStaticMethodMain {

    enum EnumStaticMethod {
      A,
      B,
      C;

      // Enum cannot be unboxed if it has a static method, we do not inline so the method is
      // present.
      @NeverInline
      static int foo() {
        return Math.addExact(-1, 0);
      }
    }

    public static void main(String[] args) {
      System.out.println(EnumStaticMethod.A.ordinal());
      System.out.println(0);
      System.out.println(EnumStaticMethod.foo());
      System.out.println(-1);
    }
  }

  static class EnumVirtualMethodMain {

    public static void main(String[] args) {
      EnumVirtualMethod e1 = EnumVirtualMethod.A;
      System.out.println(e1.ordinal());
      System.out.println(0);
      System.out.println(e1.valueOf());
      System.out.println(-1);
    }

    enum EnumVirtualMethod {
      A,
      B,
      C;

      // Enum cannot be unboxed if it has a virtual method, we do not inline so the method is
      // present.
      @NeverInline
      int valueOf() {
        return Math.addExact(-1, 0);
      }
    }
  }
}
