// 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.classmerging.vertical;

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

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import java.io.IOException;
import java.lang.Thread.State;
import java.util.concurrent.ExecutionException;
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 VerticalClassMergerSynchronizedMethodTest extends TestBase {

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    // The 4.0.4 runtime will flakily mark threads as blocking and report DEADLOCKED.
    return getTestParameters()
        .withDexRuntimesStartingFromExcluding(Version.V4_0_4)
        .withAllApiLevels()
        .build();
  }

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

  @Test
  public void testOnRuntime() throws IOException, CompilationFailedException, ExecutionException {
    testForRuntime(parameters.getRuntime(), parameters.getApiLevel())
        .addInnerClasses(VerticalClassMergerSynchronizedMethodTest.class)
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutput("Hello World!");
  }

  @Test
  public void testNoMergingOfClassUsedInMonitor()
      throws IOException, CompilationFailedException, ExecutionException {
    testForR8(parameters.getBackend())
        .addInnerClasses(VerticalClassMergerSynchronizedMethodTest.class)
        .addKeepMainRule(Main.class)
        .enableNoVerticalClassMergingAnnotations()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutput("Hello World!")
        .inspect(inspector -> assertThat(inspector.clazz(LockOne.class), isPresent()));
  }

  private interface I {

    void action();
  }

  // Will be merged into LockTwo.
  abstract static class LockOne {

    static synchronized void acquire(I c) {
      c.action();
    }
  }

  @NoVerticalClassMerging
  public static class LockTwo extends LockOne {

    static synchronized void acquire(I c) {
      Main.inTwoCritical = true;
      while (!Main.inThreeCritical) {}
      c.action();
    }
  }

  @NoVerticalClassMerging
  public static class LockThree {

    static synchronized void acquire(I c) {
      Main.inThreeCritical = true;
      while (!Main.inTwoCritical) {}
      c.action();
    }
  }

  public static class AcquireOne implements I {

    @Override
    public void action() {
      LockOne.acquire(() -> System.out.print("Hello "));
    }
  }

  public static class AcquireThree implements I {

    @Override
    public void action() {
      LockThree.acquire(() -> System.out.print("World!"));
    }
  }

  public static class Main {

    static volatile boolean inTwoCritical = false;
    static volatile boolean inThreeCritical = false;
    static volatile boolean arnoldWillNotBeBack = false;

    private static volatile Thread t1 = new Thread(Main::lockThreeThenOne);
    private static volatile Thread t2 = new Thread(Main::lockTwoThenThree);
    private static volatile Thread terminator = new Thread(Main::arnold);

    public static void main(String[] args) {
      t1.start();
      t2.start();
      // This thread is started to ensure termination in case we are rewriting incorrectly.
      terminator.start();

      while (!arnoldWillNotBeBack) {}
    }

    static void lockThreeThenOne() {
      LockThree.acquire(new AcquireOne());
    }

    static void lockTwoThenThree() {
      LockTwo.acquire(new AcquireThree());
    }

    static void arnold() {
      while (t1.getState() != State.TERMINATED || t2.getState() != State.TERMINATED) {
        if (t1.getState() == State.BLOCKED && t2.getState() == State.BLOCKED) {
          System.err.println("DEADLOCKED!");
          System.exit(1);
          break;
        }
      }
      arnoldWillNotBeBack = true;
    }
  }
}
