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

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.FieldReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final String EXPECTED =
      StringUtils.lines(
          "" + TestClass.z,
          "" + TestClass.b,
          "" + TestClass.c,
          "" + TestClass.s,
          "" + TestClass.i,
          "" + TestClass.j,
          "" + TestClass.f,
          "" + TestClass.d,
          "foo");

  private final TestParameters parameters;

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

  public FieldValueTypesInspectionTest(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(this::inspection))
        .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(this::inspection))
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
    assertFound();
  }

  private int foundFields = 0;

  private void inspection(Inspector inspector) {
    inspector.forEachClass(
        classInspector -> {
          classInspector.forEachField(
              fieldInspector -> {
                foundFields++;
                FieldReference reference = fieldInspector.getFieldReference();
                ValueInspector value = fieldInspector.getInitialValue().get();
                assertEquals(reference.getFieldType(), value.getTypeReference());
                String name = reference.getFieldName();
                boolean isBoolean = name.equals("z");
                boolean isByte = name.equals("b");
                boolean isChar = name.equals("c");
                boolean isShort = name.equals("s");
                boolean isInt = name.equals("i");
                boolean isLong = name.equals("j");
                boolean isFloat = name.equals("f");
                boolean isDouble = name.equals("d");
                boolean isString = name.equals("str");
                assertEquals(isBoolean, value.isBooleanValue());
                assertEquals(isByte, value.isByteValue());
                assertEquals(isChar, value.isCharValue());
                assertEquals(isShort, value.isShortValue());
                assertEquals(isInt, value.isIntValue());
                assertEquals(isLong, value.isLongValue());
                assertEquals(isFloat, value.isFloatValue());
                assertEquals(isDouble, value.isDoubleValue());
                assertEquals(isString, value.isStringValue());
                if (isBoolean) {
                  assertEquals(Reference.BOOL, reference.getFieldType());
                  assertEquals(TestClass.z, value.asBooleanValue().getBooleanValue());
                } else {
                  assertNull(value.asBooleanValue());
                }
                if (isByte) {
                  assertEquals(Reference.BYTE, reference.getFieldType());
                  assertEquals(TestClass.b, value.asByteValue().getByteValue());
                } else {
                  assertNull(value.asByteValue());
                }
                if (isChar) {
                  assertEquals(Reference.CHAR, reference.getFieldType());
                  assertEquals(TestClass.c, value.asCharValue().getCharValue());
                } else {
                  assertNull(value.asCharValue());
                }
                if (isShort) {
                  assertEquals(Reference.SHORT, reference.getFieldType());
                  assertEquals(TestClass.s, value.asShortValue().getShortValue());
                } else {
                  assertNull(value.asShortValue());
                }
                if (isInt) {
                  assertEquals(Reference.INT, reference.getFieldType());
                  assertEquals(TestClass.i, value.asIntValue().getIntValue());
                } else {
                  assertNull(value.asIntValue());
                }
                if (isLong) {
                  assertEquals(Reference.LONG, reference.getFieldType());
                  assertEquals(TestClass.j, value.asLongValue().getLongValue());
                } else {
                  assertNull(value.asLongValue());
                }
                if (isFloat) {
                  assertEquals(Reference.FLOAT, reference.getFieldType());
                  assertEquals(
                      Float.floatToRawIntBits(TestClass.f),
                      Float.floatToRawIntBits(value.asFloatValue().getFloatValue()));
                } else {
                  assertNull(value.asFloatValue());
                }
                if (isDouble) {
                  assertEquals(Reference.DOUBLE, reference.getFieldType());
                  assertEquals(
                      Double.doubleToRawLongBits(TestClass.d),
                      Double.doubleToRawLongBits(value.asDoubleValue().getDoubleValue()));
                } else {
                  assertNull(value.asDoubleValue());
                }
                if (isString) {
                  assertEquals(Reference.classFromClass(String.class), reference.getFieldType());
                  assertEquals(TestClass.str, value.asStringValue().getStringValue());
                } else {
                  assertNull(value.asStringValue());
                }
              });
        });
  }

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

  static class TestClass {
    public static final boolean z = true;
    public static final byte b = 2;
    public static final char c = 4;
    public static final short s = 8;
    public static final int i = 16;
    public static final long j = 32L;
    public static final float f = 64.1F;
    public static final double d = 128.1D;
    public static final String str = "foo";

    public static void main(String[] args) {
      System.out.println(z);
      System.out.println(b);
      System.out.println(c);
      System.out.println(s);
      System.out.println(i);
      System.out.println(j);
      System.out.println(f);
      System.out.println(d);
      System.out.println(str);
    }
  }
}
