// 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.classmerging;

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

import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
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.FoundClassSubject;
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;

/**
 * This test checks that the static class inliner does not merge classes in situations where a merge
 * operation could lead to a regression in code size because of reduced inlining opportunities.
 */
@RunWith(Parameterized.class)
public class InliningAfterStaticClassMergerTest extends TestBase {

  // A class that implements a library class.
  static class StaticMergeCandidateA implements Cloneable {

    // Cannot be inlined into TestClass.main() because the static initialization of this class could
    // have side-effects; in order for R8 to be conservative, library classes are treated as if
    // their static initialization could have side-effects.
    @NeverPropagateValue
    public static String m() {
      return "StaticMergeCandidateA.m()";
    }
  }

  static class StaticMergeCandidateB {

    // Can be inlined into TestClass.main() because the static initialization of this class has no
    // side-effects.
    @NeverPropagateValue
    public static String m() {
      return "StaticMergeCandidateB.m()";
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      System.out.println(StaticMergeCandidateA.m());
      System.out.print(StaticMergeCandidateB.m());
    }
  }

  private final TestParameters parameters;

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

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  @Test
  public void testMethodsAreInlined() throws Exception {
    String expected =
        StringUtils.joinLines("StaticMergeCandidateA.m()", "StaticMergeCandidateB.m()");

    testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expected);

    CodeInspector inspector =
        testForR8(parameters.getBackend())
            .addProgramClasses(
                TestClass.class, StaticMergeCandidateA.class, StaticMergeCandidateB.class)
            .addKeepMainRule(TestClass.class)
            .addOptionsModification(
                options -> options.libraryInterfacesMayHaveStaticInitialization = true)
            .enableMemberValuePropagationAnnotations()
            .noMinification()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), TestClass.class)
            .assertSuccessWithOutput(expected)
            .inspector();

    // Check that StaticMergeCandidateB has been removed.
    List<FoundClassSubject> classes =
        inspector.allClasses().stream()
            .filter(clazz -> clazz.getOriginalName().contains("StaticMergeCandidate"))
            .collect(Collectors.toList());
    assertEquals(1, classes.size());

    FoundClassSubject clazz = classes.get(0);
    assertEquals(StaticMergeCandidateA.class.getTypeName(), clazz.getOriginalName());

    // Check that StaticMergeCandidateB.m() has been inlined.
    assertEquals(0, clazz.allMethods().size());

    // Check that a static field has been synthesized in order to trigger class initialization.
    assertEquals(1, clazz.allStaticFields().size());
    assertEquals("$r8$clinit", clazz.allStaticFields().get(0).getOriginalName());

    // Check that the test class only has a main method.
    ClassSubject classSubject = inspector.clazz(TestClass.class);
    assertThat(classSubject, isPresent());
    assertEquals(1, classSubject.allMethods().size());
  }
}
