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

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.StringUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import org.junit.Test;

public class SynchronizedMethodTestRunner extends DebugInfoTestBase {

  static Class clazz = SynchronizedMethodTest.class;

  @Test
  public void testSynchronizedMethod() throws Exception {
    AndroidApp d8App = compileWithD8(clazz);

    String expected = StringUtils.lines("42", "42", "2", "2");
    assertEquals(expected, runOnJava(clazz));
    assertEquals(expected, runOnArt(d8App, clazz.getCanonicalName()));

    checkSyncStatic(inspectMethod(d8App, clazz, "int", "syncStatic", "int"));

    checkSyncInstance(inspectMethod(d8App, clazz, "int", "syncInstance", "int"));

    checkThrowing(inspectMethod(d8App, clazz, "int", "throwing", "int"));

    checkMonitorExitRegression(inspectMethod(d8App, clazz, "int", "monitorExitRegression", "int"));
  }

  private void checkSyncStatic(DebugInfoInspector info) {
    info.checkStartLine(9);
    info.checkLineHasExactLocals(9, "x", "int");
    info.checkLineHasExactLocals(10, "x", "int");
    info.checkNoLine(11);
    info.checkLineHasExactLocals(12, "x", "int");
    info.checkNoLine(13);
  }

  private void checkSyncInstance(DebugInfoInspector info) {
    String[] locals = {"this", clazz.getCanonicalName(), "x", "int"};
    info.checkStartLine(16);
    info.checkLineHasExactLocals(16, locals);
    info.checkLineHasExactLocals(17, locals);
    info.checkNoLine(18);
    info.checkLineHasExactLocals(19, locals);
    info.checkNoLine(20);
  }

  private void checkThrowing(DebugInfoInspector info) {
    info.checkStartLine(23);
    info.checkLineHasExactLocals(23, "cond", "int");
    info.checkLineHasExactLocals(24, "cond", "int", "x", "int");
    info.checkLineHasExactLocals(25, "cond", "int", "x", "int");
    info.checkNoLine(26);
    info.checkLineHasExactLocals(27, "cond", "int", "x", "int");
  }

  private void checkMonitorExitRegression(DebugInfoInspector info) {
    info.checkStartLine(31);
    for (int line : Arrays.asList(32, 34, 36, 38, 40, 42, 44, 48, 50, 52)) {
      info.checkLineHasExactLocals(line, "cond", "int", "x", "int");
    }
  }

  @Test
  public void testMonitorExitLineInRelease()
      throws CompilationFailedException, IOException, ExecutionException {
    AndroidAppConsumers sink = new AndroidAppConsumers();
    D8.run(D8Command.builder()
        .addProgramFiles(ToolHelper.getClassFileForTestClass(clazz))
        .setMode(CompilationMode.RELEASE)
        .setProgramConsumer(sink.wrapDexIndexedConsumer(null))
        .build());
    AndroidApp app = sink.build();
    DebugInfoInspector inspector = inspectMethod(app, clazz, "int", "syncStatic", "int");
    // The first line of syncStatic is 9 and thus the synthetic exit for the exceptional case will
    // have line number 8. In a release build we want to ensure that the synthetic exit does not
    // have an associated line.
    inspector.checkStartLine(9);
    inspector.checkNoLine(8);
    // Also ensure we did not emit a preamble position at line zero.
    inspector.checkNoLine(0);
  }
}
