// 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.ir.optimize.unusedarguments;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
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 UnusedAndUninstantiatedTypesTest extends TestBase {

  private final TestParameters parameters;

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

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

  @Test
  public void testUnusedAndUninstantiatedTypes() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(UnusedAndUninstantiatedTypesTest.class)
        .addKeepMainRule(Main.class)
        .noMinification()
        .enableInliningAnnotations()
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(this::assertMethodsAreThere)
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(
            "nothing",
            "uninstantiatedThenUnused null",
            "unusedThenUninstantiated null",
            "doubleUninstantiatedThenUnused null and null",
            "doubleUnusedThenUninstantiated null and null",
            "tripleUninstantiatedThenUnused null and null and null",
            "tripleUnusedThenUninstantiated null and null and null",
            "withWideParameters null and null and null");
  }

  private void assertMethodsAreThere(CodeInspector i) {
    List<FoundMethodSubject> methods = i.clazz(Main.class).allMethods();
    assertEquals(9, methods.size());
    for (FoundMethodSubject method : methods) {
      if (!method.getMethod().method.name.toString().equals("main")) {
        assertEquals(0, method.getMethod().method.getArity());
      }
    }
  }

  @SuppressWarnings("SameParameterValue")
  static class Main {

    public static void main(String[] args) {
      uninstantiatedAndUnused(null);
      uninstantiatedThenUnused(null, new Unused());
      unusedThenUninstantiated(new Unused(), null);
      doubleUninstantiatedThenUnused(null, new Unused(), null, new Unused());
      doubleUnusedThenUninstantiated(new Unused(), null, new Unused(), null);
      tripleUninstantiatedThenUnused(null, new Unused(), new Unused(), null, null, new Unused());
      tripleUnusedThenUninstantiated(new Unused(), null, null, new Unused(), new Unused(), null);
      withWideParameters(0L, 1L, null, null, 2L, 3L, null);
    }

    @NeverInline
    static void uninstantiatedAndUnused(UnInstantiated uninstantiated) {
      System.out.println("nothing");
    }

    @NeverInline
    static void uninstantiatedThenUnused(UnInstantiated uninstantiated, Unused unused) {
      System.out.println("uninstantiatedThenUnused " + uninstantiated);
    }

    @NeverInline
    static void unusedThenUninstantiated(Unused unused, UnInstantiated uninstantiated) {
      System.out.println("unusedThenUninstantiated " + uninstantiated);
    }

    @NeverInline
    static void doubleUninstantiatedThenUnused(
        UnInstantiated uninstantiated1,
        Unused unused1,
        UnInstantiated uninstantiated2,
        Unused unused2) {
      System.out.println(
          "doubleUninstantiatedThenUnused " + uninstantiated1 + " and " + uninstantiated2);
    }

    @NeverInline
    static void doubleUnusedThenUninstantiated(
        Unused unused1,
        UnInstantiated uninstantiated1,
        Unused unused2,
        UnInstantiated uninstantiated2) {
      System.out.println(
          "doubleUnusedThenUninstantiated " + uninstantiated1 + " and " + uninstantiated2);
    }

    @NeverInline
    static void tripleUninstantiatedThenUnused(
        UnInstantiated uninstantiated1,
        Unused unused0,
        Unused unused1,
        UnInstantiated uninstantiated0,
        UnInstantiated uninstantiated2,
        Unused unused2) {
      System.out.println(
          "tripleUninstantiatedThenUnused "
              + uninstantiated1
              + " and "
              + uninstantiated2
              + " and "
              + uninstantiated0);
    }

    @NeverInline
    static void tripleUnusedThenUninstantiated(
        Unused unused1,
        UnInstantiated uninstantiated0,
        UnInstantiated uninstantiated1,
        Unused unused0,
        Unused unused2,
        UnInstantiated uninstantiated2) {
      System.out.println(
          "tripleUnusedThenUninstantiated "
              + uninstantiated1
              + " and "
              + uninstantiated2
              + " and "
              + uninstantiated0);
    }

    @NeverInline
    static void withWideParameters(
        long longUnused0,
        long longUnused1,
        UnInstantiated uninstantiated0,
        UnInstantiated uninstantiated1,
        long longUnused2,
        long longUnused3,
        UnInstantiated uninstantiated2) {
      System.out.println(
          "withWideParameters "
              + uninstantiated1
              + " and "
              + uninstantiated2
              + " and "
              + uninstantiated0);
    }
  }

  private static class UnInstantiated {}

  private static class Unused {}
}
