// Copyright (c) 2021, 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;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.JavaCompilerTool;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.errors.InlinableStaticFinalFieldPreconditionDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class StaticFinalFieldInliningTest extends TestBase {

  static final String EXPECTED =
      StringUtils.lines("null", "const", "null", "const", "21", "42", "42.5");

  private final TestParameters parameters;

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

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

  @Test
  public void testJavaCompilers() throws Exception {
    Path output =
        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
            .addSourceFiles(
                ToolHelper.getSourceFileForTestClass(StaticFinalFieldInliningSource.class))
            .compile();

    testForJvm()
        .addProgramFiles(output)
        .run(parameters.getRuntime(), StaticFinalFieldInliningSource.class)
        .assertSuccessWithOutput(EXPECTED);

    CodeInspector inspector = new CodeInspector(output);
    assertHasStaticGet(true, "getNullObject", inspector);
    assertHasStaticGet(true, "getConstObject", inspector);
    assertHasStaticGet(true, "getNullString", inspector);
    assertHasStaticGet(false, "getConstString", inspector);
    assertHasStaticGet(true, "getNonConstInt", inspector);
    assertHasStaticGet(false, "getConstInt", inspector);
    assertHasStaticGet(false, "getConstDouble", inspector);
  }

  private static void assertHasStaticGet(
      boolean expected, String methodName, CodeInspector inspector) {
    MethodSubject method =
        inspector.clazz(StaticFinalFieldInliningSource.class).uniqueMethodWithName(methodName);
    assertEquals(
        method.getMethod().codeToString(),
        expected,
        method.streamInstructions().anyMatch(InstructionSubject::isStaticGet));
  }

  private static String makeIfRule(String fieldName) {
    return "-if class * { *** " + fieldName + "; } -keep class <1> { *** unusedField; }";
  }

  @Test
  public void testNoWarningsOnNonInlinedFields() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(StaticFinalFieldInliningSource.class)
        .addKeepMainRule(StaticFinalFieldInliningSource.class)
        .addKeepRules(makeIfRule("nullObject"))
        .addKeepRules(makeIfRule("constObject"))
        .addKeepRules(makeIfRule("nullString"))
        .addKeepRules(makeIfRule("nonConstInt"))
        .compileWithExpectedDiagnostics(TestDiagnosticMessages::assertNoWarnings);
  }

  @Test
  public void testWarningsOnMultipleMatches() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(StaticFinalFieldInliningSource.class)
        .addKeepMainRule(StaticFinalFieldInliningSource.class)
        // This rule matches both constObject (non-inlined) and constString/Int/Double (inlined).
        .addKeepRules(makeIfRule("const*"))
        .allowDiagnosticWarningMessages()
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              diagnostics.assertWarningsMatch(
                  allOf(
                      diagnosticType(InlinableStaticFinalFieldPreconditionDiagnostic.class),
                      diagnosticMessage(containsString("constString")),
                      diagnosticMessage(containsString("constInt")),
                      diagnosticMessage(containsString("constDouble")),
                      not(diagnosticMessage(containsString("constObject")))));
            });
  }

  @Test
  public void testWarningsOnInlinedFields() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(StaticFinalFieldInliningSource.class)
        .addKeepMainRule(StaticFinalFieldInliningSource.class)
        .addKeepRules(makeIfRule("constString"))
        .addKeepRules(makeIfRule("constInt"))
        .addKeepRules(makeIfRule("constDouble"))
        .allowDiagnosticWarningMessages()
        .compileWithExpectedDiagnostics(
            diagnostics ->
                diagnostics.assertWarningsMatch(
                    diagnosticMessage(containsString("constString")),
                    diagnosticMessage(containsString("constInt")),
                    diagnosticMessage(containsString("constDouble"))));
  }
}
