// 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.shaking.assumenosideeffects;

import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class AssumenosideeffectsPropagationTest extends TestBase {
  private static final Class<?> MAIN = SubsUser.class;

  enum TestConfig {
    SPECIFIC_RULES,
    NON_SPECIFIC_RULES_PARTIAL,
    NON_SPECIFIC_RULES_ALL;

    public String getKeepRules() {
      switch (this) {
        case SPECIFIC_RULES:
          return StringUtils.lines(
              // Intentionally miss sub types of Base2 for info().
              "-assumenosideeffects class **.*$Sub* {",
              "  void info(...); ",
              "}",
              // All debug() and verbose() should be removed.
              "-assumenosideeffects class **.*Sub* {",
              "  void debug(...);",
              "  void verbose(...);",
              "}"
          );
        case NON_SPECIFIC_RULES_PARTIAL:
          return StringUtils.lines(
              // Intentionally miss sub types of Base2 for debug().
              "-assumenosideeffects class **.*$Sub* {",
              "  void debug(...);"
              ,"}",
              // Targeting info() and verbose() in Base1, without wildcards.
              "-assumenosideeffects class * extends " + Base1.class.getTypeName() + " {",
              "  void info(...);",
              "  void verbose(...);",
              "}",
              // Targeting info() and verbose() in Base2, with wildcards.
              "-assumenosideeffects class * extends " + Base2.class.getTypeName() + " {",
              "  void *o*(java.lang.String);",
              "}"
          );
        case NON_SPECIFIC_RULES_ALL:
          return StringUtils.lines(
              "-assumenosideeffects class **.*Sub* {",
              "  void *(java.lang.String);",
              "}"
          );
        default:
          throw new Unreachable();
      }
    }

    public String expectedOutput(boolean enableHorizontalClassMerging) {
      switch (this) {
        case SPECIFIC_RULES:
          return enableHorizontalClassMerging
              ? StringUtils.lines(
                  "[Base2, info]: message08",
                  // Base2#info also has side effects.
                  "[Base2, info]: message4",
                  "The end")
              : StringUtils.lines(
                  // Itf#info has side effects due to the missing Base2.
                  "[Sub1, info]: message00",
                  "[Base2, info]: message08",
                  // Base2#info also has side effects.
                  "[Base2, info]: message4",
                  "The end");
        case NON_SPECIFIC_RULES_PARTIAL:
          return enableHorizontalClassMerging
              ? StringUtils.lines(
                  "[AnotherSub2, debug]: message08", "[AnotherSub2, debug]: message5", "The end")
              : StringUtils.lines(
                  "[Base1, debug]: message00",
                  "[AnotherSub2, debug]: message08",
                  "[AnotherSub2, debug]: message5",
                  "The end");
        case NON_SPECIFIC_RULES_ALL:
          return StringUtils.lines("The end");
        default:
          throw new Unreachable();
      }
    }
  }

  private final TestParameters parameters;
  private final TestConfig config;
  private final boolean enableHorizontalClassMerging;

  @Parameterized.Parameters(name = "{0}, config: {1}, horizontal: {2}")
  public static Collection<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        TestConfig.values(),
        BooleanUtils.values());
  }

  public AssumenosideeffectsPropagationTest(
      TestParameters parameters, TestConfig config, boolean enableHorizontalClassMerging) {
    this.parameters = parameters;
    this.config = config;
    this.enableHorizontalClassMerging = enableHorizontalClassMerging;
  }

  @Test
  public void testJVMOutput() throws Exception {
    assumeTrue(parameters.isCfRuntime());
    assumeTrue(config == TestConfig.SPECIFIC_RULES);
    assumeFalse(enableHorizontalClassMerging);
    testForJvm()
        .addTestClasspath()
        .run(parameters.getRuntime(), MAIN)
        .assertSuccessWithOutputLines(
            "[Sub1, info]: message00",
            "[Base1, debug]: message00",
            "[Sub1, verbose]: message00",
            "[Sub1, info]: message1",
            "[Base1, debug]: message2",
            "[Sub1, verbose]: message3",
            "[Base2, info]: message08",
            "[AnotherSub2, debug]: message08",
            "[AnotherSub2, verbose]: message08",
            "[Base2, info]: message4",
            "[AnotherSub2, debug]: message5",
            "[AnotherSub2, verbose]: message6",
            "The end");
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(AssumenosideeffectsPropagationTest.class)
        .addKeepMainRule(MAIN)
        .addKeepRules(config.getKeepRules())
        .addOptionsModification(
            options ->
                options.horizontalClassMergerOptions().enableIf(enableHorizontalClassMerging))
        .enableInliningAnnotations()
        .noMinification()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), MAIN)
        .assertSuccessWithOutput(config.expectedOutput(enableHorizontalClassMerging));
  }

  interface Itf {
    void info(String message);
    void debug(String message);
    void verbose(String message);
  }

  static abstract class Base1 implements Itf {
    public abstract void info(String message);
    public abstract void debug(String message);
    public abstract void verbose(String message);
  }

  static class Sub1 extends Base1 {
    @Override
    public void info(String message) {
      System.out.println("[Sub1, info]: " + message);
    }

    @Override
    public void debug(String message) {
      System.out.println("[Base1, debug]: " + message);
    }

    @Override
    public void verbose(String message) {
      System.out.println("[Sub1, verbose]: " + message);
    }
  }

  static class Sub2 extends Base1 {
    @Override
    public void info(String message) {
      System.out.println("[Sub2, info]: " + message);
    }

    @Override
    public void debug(String message) {
      System.out.println("[Base1, debug]: " + message);
    }

    @Override
    public void verbose(String message) {
      System.out.println("[Sub2, verbose]: " + message);
    }
  }

  static abstract class Base2 implements Itf {
    public abstract void info(String message);
    public abstract void debug(String message);
    public abstract void verbose(String message);
  }

  static class AnotherSub1 extends Base2 {
    @Override
    public void info(String message) {
      System.out.println("[Base2, info]: " + message);
    }

    @Override
    public void debug(String message) {
      System.out.println("[AnotherSub1, debug]: " + message);
    }

    @Override
    public void verbose(String message) {
      System.out.println("[AnotherSub1, verbose]: " + message);
    }
  }

  static class AnotherSub2 extends Base2 {
    @Override
    public void info(String message) {
      System.out.println("[Base2, info]: " + message);
    }

    @Override
    public void debug(String message) {
      System.out.println("[AnotherSub2, debug]: " + message);
    }

    @Override
    public void verbose(String message) {
      System.out.println("[AnotherSub2, verbose]: " + message);
    }
  }

  static class SubsUser {
    static Base1 createBase1() {
      return System.currentTimeMillis() > 0 ? new Sub1() : new Sub2();
    }

    static Base2 createBase2() {
      return System.currentTimeMillis() < 0 ? new AnotherSub1() : new AnotherSub2();
    }

    @NeverInline
    private static void testInvokeInterface(Itf itf, String message) {
      itf.info(message);
      itf.debug(message);
      itf.verbose(message);
    }

    public static void main(String... args) {
      Base1 instance1 = createBase1();
      testInvokeInterface(instance1, "message00");
      instance1.info("message1");
      instance1.debug("message2");
      instance1.verbose("message3");
      Base2 instance2 = createBase2();
      testInvokeInterface(instance2, "message08");
      instance2.info("message4");
      instance2.debug("message5");
      instance2.verbose("message6");
      System.out.println("The end");
    }
  }
}
