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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.inspector.Inspector;
import com.android.tools.r8.inspector.ValueInspector;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.StringUtils;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final String EXPECTED = StringUtils.lines("30");

  private final TestParameters parameters;

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

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

  @Test
  public void testD8() throws Exception {
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClasses(TestClass.class)
          .run(parameters.getRuntime(), TestClass.class)
          .assertSuccessWithOutput(EXPECTED);
      return;
    }
    testForD8()
        .addProgramClasses(TestClass.class)
        .setMinApi(parameters.getApiLevel())
        .apply(b -> b.getBuilder().addOutputInspection(inspector -> inspection(inspector, false)))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
    assertFound();
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClass.class)
        .addKeepClassAndMembersRules(TestClass.class)
        .setMinApi(parameters.getApiLevel())
        .apply(b -> b.getBuilder().addOutputInspection(inspector -> inspection(inspector, true)))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
    assertFound();
  }

  private int foundFields = 0;

  private void inspection(Inspector inspector, boolean isR8) {
    inspector.forEachClass(
        classInspector -> {
          classInspector.forEachField(
              fieldInspector -> {
                foundFields++;
                String name = fieldInspector.getFieldReference().getFieldName();
                assertEquals(name.contains("s"), fieldInspector.isStatic());
                assertEquals(name.contains("f"), fieldInspector.isFinal());
                assertEquals(Reference.INT, fieldInspector.getFieldReference().getFieldType());
                Optional<ValueInspector> value = fieldInspector.getInitialValue();
                if (fieldInspector.isStatic() && fieldInspector.isFinal()) {
                  // The static final 'sfi' is static initialized to 2.
                  assertTrue(value.isPresent());
                  assertEquals(2, value.get().asIntValue().getIntValue());
                } else if (fieldInspector.isStatic()) {
                  // The static 'si' is default initialized to 0 and clinit sets it to 4.
                  // R8 optimizes that to directly set 4.
                  assertTrue(value.isPresent());
                  assertEquals(isR8 ? 4 : 0, value.get().asIntValue().getIntValue());
                } else {
                  assertFalse(value.isPresent());
                }
              });
        });
  }

  private void assertFound() {
    assertEquals(4, foundFields);
  }

  static class TestClass {
    public static final int sfi = 2;
    public static int si = 4;
    public final int fi = 8;
    public int i = 16;

    public static void main(String[] args) {
      TestClass obj = new TestClass();
      System.out.println(obj.sfi + obj.si + obj.fi + obj.i);
    }
  }
}
