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

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.DesugarTestConfiguration;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.cf.code.CfArithmeticBinop;
import com.android.tools.r8.cf.code.CfArithmeticBinop.Opcode;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.code.AddLong2Addr;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

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

  private final TestParameters parameters;

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

  private boolean isCfLAdd(CfInstruction instruction) {
    return (instruction instanceof CfArithmeticBinop)
        && (((CfArithmeticBinop) instruction).getOpcode() == Opcode.Add)
        && (((CfArithmeticBinop) instruction).getType() == NumericType.LONG);
  }

  private boolean isDexAddLong(Instruction instruction) {
    return instruction instanceof AddLong2Addr;
  }

  private boolean boxedDoubleIsFiniteInvoke(InstructionSubject instruction) {
    System.out.println(instruction);
    if (instruction.isInvokeStatic()) {
      System.out.println(instruction.getMethod().qualifiedName());
    }
    return instruction.isInvokeStatic()
        && instruction.getMethod().qualifiedName().equals("java.lang.Double.isFinite");
  }

  private void checkBackportingNotRequired(CodeInspector inspector) {
    MethodSubject methodSubject = inspector.clazz(TestClass.class).uniqueMethodWithName("main");
    if (methodSubject.getProgramMethod().getDefinition().getCode().isCfCode()) {
      CfCode code = methodSubject.getProgramMethod().getDefinition().getCode().asCfCode();
      assertTrue(code.getInstructions().stream().noneMatch(this::isCfLAdd));
    } else {
      DexCode code = methodSubject.getProgramMethod().getDefinition().getCode().asDexCode();
      assertTrue(Arrays.stream(code.instructions).noneMatch(this::isDexAddLong));
    }
    assertTrue(methodSubject.streamInstructions().anyMatch(this::boxedDoubleIsFiniteInvoke));
  }

  private void checkBackportingRequired(CodeInspector inspector) {
    MethodSubject methodSubject = inspector.clazz(TestClass.class).uniqueMethodWithName("main");
    if (methodSubject.getProgramMethod().getDefinition().getCode().isCfCode()) {
      CfCode code = methodSubject.getProgramMethod().getDefinition().getCode().asCfCode();
      assertTrue(code.getInstructions().stream().anyMatch(this::isCfLAdd));
    } else {
      DexCode code = methodSubject.getProgramMethod().getDefinition().getCode().asDexCode();
      assertTrue(Arrays.stream(code.instructions).anyMatch(this::isDexAddLong));
    }
    assertTrue(methodSubject.streamInstructions().noneMatch(this::boxedDoubleIsFiniteInvoke));
  }

  private void checkBackportedIfRequired(CodeInspector inspector) {
    if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)) {
      checkBackportingNotRequired(inspector);
    } else {
      checkBackportingRequired(inspector);
    }
  }

  @Test
  public void test() throws Exception {
    testForDesugaring(parameters)
        .addInnerClasses(DesugarToClassFileBackport.class)
        .run(parameters.getRuntime(), TestClass.class)
        .inspectIf(DesugarTestConfiguration::isNotDesugared, this::checkBackportingNotRequired)
        .inspectIf(DesugarTestConfiguration::isDesugared, this::checkBackportedIfRequired)
        .assertSuccessWithOutputLines("3", "true");
  }

  static class TestClass {

    private static long getOne() {
      return 1L;
    }

    private static long getTwo() {
      return 2L;
    }

    public static void main(String[] args) {
      System.out.println(Long.sum(getOne(), getTwo()));
      System.out.println(Double.isFinite(1.0));
    }
  }
}
