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

import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethodWithName;
import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

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

  @Parameter(0)
  public TestParameters parameters;

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

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(A.class)
        .addProgramClassFileData(getProgramClassFileData())
        .addKeepClassAndMembersRules(Main.class)
        // CameraDevice is not present in rt.jar or android.jar when API<L.
        .applyIf(
            parameters.isCfRuntime() || parameters.getApiLevel().isLessThan(AndroidApiLevel.L),
            testBuilder -> testBuilder.addDontWarn("android.hardware.camera2.CameraDevice"))
        // CameraDeviceUser can only be merged with A when min API>=L.
        .addHorizontallyMergedClassesInspector(
            inspector ->
                inspector
                    .applyIf(
                        parameters.isDexRuntime()
                            && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L),
                        i -> i.assertIsCompleteMergeGroup(A.class, CameraDeviceUser.class))
                    .assertNoOtherClassesMerged())
        .setMinApi(parameters.getApiLevel())
        .compile()
        // CameraDeviceUser.m() can only be inlined when min API>=L.
        .inspect(
            inspector -> {
              if (parameters.isDexRuntime()
                  && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L)) {
                assertThat(inspector.clazz(CameraDeviceUser.class), isAbsent());
              } else {
                ClassSubject cameraDeviceUserClassSubject = inspector.clazz(CameraDeviceUser.class);
                assertThat(cameraDeviceUserClassSubject, isPresent());

                MethodSubject mMethodSubject =
                    cameraDeviceUserClassSubject.uniqueMethodWithName("m");
                assertThat(mMethodSubject, isPresent());
                assertThat(mMethodSubject, invokesMethodWithName("close"));
              }
            });
  }

  private static List<byte[]> getProgramClassFileData() throws IOException {
    String oldDescriptor = DescriptorUtils.javaTypeToDescriptor(CameraDevice.class.getTypeName());
    String newDescriptor = "Landroid/hardware/camera2/CameraDevice;";
    return ImmutableList.of(
        transformer(Main.class)
            .replaceClassDescriptorInMembers(oldDescriptor, newDescriptor)
            .replaceClassDescriptorInMethodInstructions(oldDescriptor, newDescriptor)
            .transform(),
        transformer(CameraDeviceUser.class)
            .replaceClassDescriptorInMembers(oldDescriptor, newDescriptor)
            .replaceClassDescriptorInMethodInstructions(oldDescriptor, newDescriptor)
            .transform());
  }

  // The following classes are transformed to use android.hardware.camera2.CameraDevice.
  static class Main {

    public static void main(String[] args) {
      int minApi = args.length;
      if (minApi >= 21) {
        new CameraDeviceUser().m(getCameraDevice());
      } else {
        System.out.println(new A());
      }
    }

    // @Keep
    static CameraDevice getCameraDevice() {
      return null;
    }
  }

  static class A {}

  static class CameraDeviceUser {

    public void m(CameraDevice cd) {
      if (cd != null) {
        cd.close();
      }
    }
  }

  abstract static class CameraDevice {

    abstract void close();
  }
}
