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

import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.getMainClass;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
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 MinimumNumberOfBridgesGenerated extends TestBase {

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

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters()
        .withCfRuntimesStartingFromIncluding(CfVm.JDK11)
        .withDexRuntime(DexVm.Version.first())
        .withDexRuntime(DexVm.Version.last())
        .withAllApiLevels()
        .build();
  }

  @Test
  public void testOnlyRequiredBridges() throws Exception {
    if (parameters.isDexRuntime()) {
      FullNestOnProgramPathTest.d8CompilationResult
          .apply(parameters.getApiLevel())
          .inspect(this::assertOnlyRequiredBridges);
    }
    FullNestOnProgramPathTest.r8CompilationResult
        .apply(parameters.getBackend(), parameters.getApiLevel())
        .inspect(this::assertOnlyRequiredBridges);
  }

  private void assertOnlyRequiredBridges(CodeInspector inspector) {
    // The following 2 classes have an extra private member which does not require a bridge.

    // Two bridges for method and staticMethod.
    int methodNumBridges = parameters.isCfRuntime() ? 0 : 2;
    ClassSubject methodMainClass = inspector.clazz(getMainClass("methods"));
    assertEquals(
        methodNumBridges, methodMainClass.allMethods(this::isNestBridge).size());

    // Two bridges for method and staticMethod.
    int constructorNumBridges = parameters.isCfRuntime() ? 0 : 1;
    ClassSubject constructorMainClass = inspector.clazz(getMainClass("constructors"));
    assertEquals(
        constructorNumBridges,
        constructorMainClass.allMethods(this::isNestBridge).size());

    // Four bridges for field and staticField, both get & set.
    int fieldNumBridges = parameters.isCfRuntime() ? 0 : 4;
    ClassSubject fieldMainClass = inspector.clazz(getMainClass("fields"));
    assertEquals(
        fieldNumBridges, fieldMainClass.allMethods(this::isNestBridge).size());
  }

  private boolean isNestBridge(FoundMethodSubject methodSubject) {
    DexEncodedMethod method = methodSubject.getMethod();
    if (method.isInstanceInitializer()) {
      return method.method.proto.parameters.size() > 0 && method.method.proto.parameters.values[
          method.method.proto.parameters.size() - 1].toSourceString()
          .contains(NestBasedAccessDesugaring.NEST_CONSTRUCTOR_NAME);
    }
    return method.method.name.toString()
        .startsWith(NestBasedAccessDesugaring.NEST_ACCESS_NAME_PREFIX);
  }
}
