// Copyright (c) 2016, 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.dex;

import static com.android.tools.r8.dex.Constants.DEX_MAGIC_SIZE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.EncodedValueUtils;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class EncodedFloatingValueTest {
  private final double value;

  public EncodedFloatingValueTest(double value) {
    this.value = value;
  }

  @Parameters(name = "{0}")
  public static Collection<Double> data() {
    return Arrays.asList(
        0.0,
        1.0,
        0.5,
        Double.longBitsToDouble(1), // Lowest bit is 1 in double
        Double.longBitsToDouble(0x10), // Bits on byte boundary are 1.
        Double.longBitsToDouble(0x08),
        Double.longBitsToDouble(4607071218809329336L),  // Test a real long (regression).
        (double) (Float.intBitsToFloat(1)), // Lowest bit is 1 in float
        (double) (Float.intBitsToFloat(0x10)), // Bits on byte boundary are 1
        (double) (Float.intBitsToFloat(0x08))
    );
  }

  // Create a DexReader with correct file magic followed by the argument bytes. Positions the
  // DexReader after the file magic.
  private DexReader createDexFileWithContent(byte[] bytes) {
    DexOutputBuffer buffer = new DexOutputBuffer();
    buffer.putBytes(Constants.DEX_FILE_MAGIC_PREFIX);
    buffer.putBytes(AndroidApiLevel.B.getDexVersion().getBytes());
    buffer.putByte(Constants.DEX_FILE_MAGIC_SUFFIX);
    buffer.putBytes(bytes);
    DexReader dexReader = new DexReader(Origin.unknown(), buffer.asArray());
    dexReader.position(DEX_MAGIC_SIZE);
    return dexReader;
  }

  @Test
  public void testEncodeDecodeDouble() {
    byte[] bytes = EncodedValueUtils.encodeDouble(value);
    assertTrue(bytes.length <= Double.BYTES);
    DexReader dexReader = createDexFileWithContent(bytes);
    Assert.assertEquals(value, EncodedValueUtils.parseDouble(dexReader, bytes.length), 0.0);
  }

  @Test
  public void testEncodeDecodeFloat() {
    byte[] bytes = EncodedValueUtils.encodeFloat((float) value);
    assertTrue(bytes.length <= Float.BYTES);
    DexReader dexReader = createDexFileWithContent(bytes);
    Assert.assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, bytes.length), 0.0f);
  }

  @Test
  public void testEncodeDecodeDoubleWithDexBuffer() {
    DexOutputBuffer buffer = new DexOutputBuffer();
    int length = EncodedValueUtils.putDouble(buffer, value);
    assertTrue(length <= Double.BYTES);
    byte[] bytes = buffer.asArray();
    DexReader dexReader = createDexFileWithContent(bytes);
    assertEquals(value, EncodedValueUtils.parseDouble(dexReader, length), 0.0);
  }

  @Test
  public void testEncodeDecodeFloatWithDexBuffer() {
    DexOutputBuffer buffer = new DexOutputBuffer();
    int length = EncodedValueUtils.putFloat(buffer, (float) value);
    assertTrue(length <= Float.BYTES);
    byte[] bytes = buffer.asArray();
    DexReader dexReader = createDexFileWithContent(bytes);
    assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, length), 0.0f);
  }
}
