// 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.ir.analysis.type;

import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.FLOAT;
import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.INT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ir.analysis.AnalysisTestBase;
import com.android.tools.r8.ir.code.ArrayGet;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Value;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ArrayTypeTest extends AnalysisTestBase {

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

  public ArrayTypeTest(TestParameters parameters) throws Exception {
    super(parameters, TestClass.class);
  }

  @Test
  public void testArray() throws Exception {
    buildAndCheckIR("arrayTest", arrayTestInspector());
  }

  @Test
  public void testNestedArray() throws Exception {
    buildAndCheckIR("nestedArrayTest", nestedArrayTestInspector());
  }

  @Test
  public void testJoinOfArraysForPrimitivesSmallerThanInt() throws Exception {
    buildAndCheckIR(
        "joinOfArraysForPrimitivesSmallerThanInt",
        joinOfArraysForPrimitivesSmallerThanInt());
  }

  private static Consumer<IRCode> arrayTestInspector() {
    return code -> {
      for (Instruction instruction : code.instructions()) {
        if (instruction.isArrayGet() || instruction.isArrayPut()) {
          Value array, value;
          if (instruction.isArrayGet()) {
            ArrayGet arrayGetInstruction = instruction.asArrayGet();
            array = arrayGetInstruction.array();
            value = arrayGetInstruction.outValue();
          } else {
            ArrayPut arrayPutInstruction = instruction.asArrayPut();
            array = arrayPutInstruction.array();
            value = arrayPutInstruction.value();
          }

          assertTrue(array.getTypeLattice().isArrayType());

          ArrayTypeLatticeElement arrayType = array.getTypeLattice().asArrayTypeLatticeElement();
          TypeLatticeElement elementType = arrayType.getArrayMemberTypeAsMemberType();

          assertEquals(FLOAT, elementType);
          assertEquals(FLOAT, value.getTypeLattice());
        }
      }
    };
  }

  private static Consumer<IRCode> nestedArrayTestInspector() {
    return code -> {
      {
        ArrayPut arrayPutInstruction = getMatchingInstruction(code, Instruction::isArrayPut);

        Value array = arrayPutInstruction.array();
        Value value = arrayPutInstruction.value();

        assertTrue(array.getTypeLattice().isArrayType());

        ArrayTypeLatticeElement arrayType = array.getTypeLattice().asArrayTypeLatticeElement();
        TypeLatticeElement elementType = arrayType.getArrayMemberTypeAsMemberType();

        assertEquals(FLOAT, elementType);
        assertEquals(FLOAT, value.getTypeLattice());
      }

      {
        ConstNumber constNumberInstruction =
            getMatchingInstruction(
                code,
                instruction ->
                    instruction.isConstNumber() && instruction.asConstNumber().getRawValue() != 0);
        assertEquals(FLOAT, constNumberInstruction.outValue().getTypeLattice());
      }
    };
  }

  private static Consumer<IRCode> joinOfArraysForPrimitivesSmallerThanInt() {
    return code -> {
      int phiCount = 0;
      for (BasicBlock block : code.blocks) {
        for (Phi phi : block.getPhis()) {
          phiCount++;
          assertEquals(INT, phi.getTypeLattice());
        }
      }
      assertEquals(2, phiCount);
    };
  }

  static class TestClass {

    public static void arrayTest() {
      float nans[] = {
        Float.NaN,
        Float.intBitsToFloat(0x7f800001),
        Float.intBitsToFloat(0x7fC00000),
        Float.intBitsToFloat(0x7fffffff),
        Float.intBitsToFloat(0xff800001),
        Float.intBitsToFloat(0x7fC00000),
        Float.intBitsToFloat(0xffffffff),
      };
      nans[0] = nans[0];
      nans[1] = nans[1];
      nans[2] = nans[2];
      nans[3] = nans[3];
      nans[4] = nans[4];
      nans[5] = nans[5];
      nans[6] = nans[6];
    }

    public static void nestedArrayTest(float[][] array) {
      float x = 1f;
      array[0][0] = x;
    }

    public static void joinOfArraysForPrimitivesSmallerThanInt(
        boolean predicate, byte[] bs, char[] cs) {
      char s = (char) (predicate ? bs[0] : cs[0]);
      byte b = (predicate ? bs[0] : bs[0]);
      if (s == b) {
        System.out.println("Meh, just to use variables.");
      }
    }
  }
}
