// Copyright (c) 2019, 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.optimize.redundantconstnumber;

import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.BooleanUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
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 B124152497 extends TestBase {

  private final Class<?> clazz;
  private final boolean forceRedundantConstNumberRemovalOnDalvik;
  private final TestParameters parameters;

  @Parameters(name = "{2}, class: {0}, force redundant const number removal: {1}")
  public static List<Object[]> data() {
    return buildParameters(
        ImmutableList.of(
            BooleanTestClass.class,
            ByteTestClass.class,
            CharTestClass.class,
            FloatTestClass.class,
            ShortTestClass.class),
        BooleanUtils.values(),
        getTestParameters().withAllRuntimes().build());
  }

  public B124152497(
      Class<?> clazz, boolean forceRedundantConstNumberRemovalOnDalvik, TestParameters parameters) {
    this.clazz = clazz;
    this.forceRedundantConstNumberRemovalOnDalvik = forceRedundantConstNumberRemovalOnDalvik;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    assumeTrue(!forceRedundantConstNumberRemovalOnDalvik || isDalvik());
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(clazz)
            .addKeepMainRule(clazz)
            .addOptionsModification(
                options -> {
                  if (forceRedundantConstNumberRemovalOnDalvik) {
                    assertTrue(isDalvik());
                    options.testing.forceRedundantConstNumberRemoval = true;
                    options.enableRedundantConstNumberOptimization = true;
                  }
                })
            .enableInliningAnnotations()
            .setMinApi(parameters.getRuntime())
            .compile()
            .run(parameters.getRuntime(), clazz);
    if (isExpectedToSucceed()) {
      result.assertSuccessWithOutputLines(getExpectedOutput());
    } else {
      result.assertFailureWithErrorThatMatches(containsString("java.lang.VerifyError"));
    }
  }

  private boolean isDalvik() {
    return parameters.getRuntime().isDex()
        && parameters.getRuntime().asDex().getVm().getVersion().isOlderThanOrEqual(Version.V4_4_4);
  }

  private boolean isExpectedToSucceed() {
    return !isDalvik()
        || !forceRedundantConstNumberRemovalOnDalvik
        || clazz == BooleanTestClass.class
        || clazz == FloatTestClass.class;
  }

  private String getExpectedOutput() {
    if (clazz == BooleanTestClass.class) {
      return "true";
    }
    if (clazz == ByteTestClass.class) {
      return "42";
    }
    if (clazz == CharTestClass.class) {
      return "*";
    }
    if (clazz == FloatTestClass.class) {
      return "42.0";
    }
    if (clazz == ShortTestClass.class) {
      return "42";
    }
    throw new Unreachable();
  }

  static class BooleanTestClass {

    public static void main(String[] args) {
      int value = getInt();
      if (value == 1) {
        consumeBoolean(true);
      }
    }

    @NeverInline
    private static int getInt() {
      return System.currentTimeMillis() >= 0 ? 1 : 0;
    }

    @NeverInline
    private static void consumeBoolean(boolean value) {
      System.out.println(value);
    }
  }

  static class ByteTestClass {

    public static void main(String[] args) {
      int value = getInt();
      if (value == 42) {
        consumeByte((byte) 42);
      }
    }

    @NeverInline
    private static int getInt() {
      return System.currentTimeMillis() >= 0 ? 42 : 0;
    }

    @NeverInline
    private static void consumeByte(byte value) {
      System.out.println(value);
    }
  }

  static class CharTestClass {

    public static void main(String[] args) {
      int value = getInt();
      if (value == 42) {
        consumeChar('*'); // '*' == (char) 42
      }
    }

    @NeverInline
    private static int getInt() {
      return System.currentTimeMillis() >= 0 ? 42 : 0;
    }

    @NeverInline
    private static void consumeChar(char value) {
      System.out.println(value);
    }
  }

  static class FloatTestClass {

    public static void main(String[] args) {
      int value = getInt();
      if (value == 42) {
        consumeFloat(42);
      }
    }

    @NeverInline
    private static int getInt() {
      return System.currentTimeMillis() >= 0 ? 42 : 0;
    }

    @NeverInline
    private static void consumeFloat(float value) {
      System.out.println(value);
    }
  }

  static class ShortTestClass {

    public static void main(String[] args) {
      int value = getInt();
      if (value == 42) {
        consumeShort((short) 42);
      }
    }

    @NeverInline
    private static int getInt() {
      return System.currentTimeMillis() >= 0 ? 42 : 0;
    }

    @NeverInline
    private static void consumeShort(short value) {
      System.out.println(value);
    }
  }
}
