// 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.shaking.ifrule.classstaticizer;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
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.FoundMethodSubject;
import java.util.List;
import java.util.stream.Collectors;
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 IfRuleWithClassStaticizerTest extends TestBase {

  private final Backend backend;

  @Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return ToolHelper.getBackends();
  }

  public IfRuleWithClassStaticizerTest(Backend backend) {
    this.backend = backend;
  }

  @Test
  public void test() throws Exception {
    String expectedOutput = StringUtils.lines("In method()");

    if (backend == Backend.CF) {
      testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput);
    }

    CodeInspector inspector =
        testForR8(backend)
            .addInnerClasses(IfRuleWithClassStaticizerTest.class)
            .addKeepMainRule(TestClass.class)
            .addKeepRules(
                "-if class " + StaticizerCandidate.Companion.class.getTypeName() + " {",
                "  public !static void method();",
                "}",
                "-keep class " + Unused.class.getTypeName())
            .enableInliningAnnotations()
            .enableClassInliningAnnotations()
            // TODO(119626580): Remove when resolved.
            .addOptionsModification(options -> options.enableClassStaticizer = true)
            .run(TestClass.class)
            .assertSuccessWithOutput(expectedOutput)
            .inspector();

    ClassSubject classSubject = inspector.clazz(StaticizerCandidate.class);
    assertThat(classSubject, isPresent());

    if (backend == Backend.CF) {
      // The class staticizer is not enabled for CF.
      assertThat(inspector.clazz(Unused.class), isPresent());
    } else {
      assert backend == Backend.DEX;

      // There should be a static method on StaticizerCandidate after staticizing.
      List<FoundMethodSubject> staticMethods =
          classSubject.allMethods().stream()
              .filter(method -> method.isStatic() && !method.isClassInitializer())
              .collect(Collectors.toList());
      assertEquals(1, staticMethods.size());
      assertEquals(
          "void " + StaticizerCandidate.Companion.class.getTypeName() + ".method()",
          staticMethods.get(0).getOriginalSignature().toString());

      // The Companion class should not be present after staticizing.
      assertThat(inspector.clazz(StaticizerCandidate.Companion.class), not(isPresent()));

      // TODO(b/122867080): The Unused class should be present due to the -if rule.
      assertThat(inspector.clazz(Unused.class), not(isPresent()));
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      StaticizerCandidate.companion.method();
    }
  }

  @NeverClassInline
  static class StaticizerCandidate {

    static final Companion companion = new Companion();

    @NeverClassInline
    static class Companion {

      @NeverInline
      public void method() {
        System.out.println("In method()");
      }
    }
  }

  static class Unused {}
}
