// Copyright (c) 2022, 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 static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexDebugEntry;
import com.android.tools.r8.graph.DexDebugEntryBuilder;
import com.android.tools.r8.graph.DexDebugInfo;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.utils.StringUtils;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class Regress216178582Test extends TestBase {

  static final String EXPECTED = StringUtils.lines("Hello world!");

  private final TestParameters parameters;

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

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

  @Test
  public void test() throws Exception {
    Path out =
        testForR8(parameters.getBackend())
            .addInnerClasses(Regress216178582Test.class)
            .setMinApi(parameters.getApiLevel())
            .addKeepMainRule(TestClass.class)
            .addKeepAttributeLineNumberTable()
            .addOptionsModification(o -> o.testing.forcePcBasedEncoding = true)
            .compile()
            .inspect(
                inspector -> {
                  DexEncodedMethod method =
                      inspector.clazz(TestClass.class).mainMethod().getMethod();
                  DexCode code = method.getCode().asDexCode();
                  if (parameters
                      .getApiLevel()
                      .isGreaterThanOrEqualTo(apiLevelWithPcAsLineNumberSupport())) {
                    assertNull(code.getDebugInfo());
                    return;
                  }
                  assertTrue(code.getDebugInfo().isPcBasedInfo());
                  // Force convert the PC info to events.
                  code.setDebugInfo(DexDebugInfo.convertToEventBased(code, inspector.getFactory()));
                  List<DexDebugEntry> entries =
                      new DexDebugEntryBuilder(method, inspector.getFactory()).build();
                  Iterator<DexDebugEntry> it = entries.iterator();
                  int pc = 0;
                  for (Instruction instruction : code.instructions) {
                    if (instruction.canThrow()) {
                      DexDebugEntry next = it.next();
                      assertEquals(
                          "Invalid entry "
                              + next
                              + " at pc "
                              + StringUtils.hexString(pc, 2)
                              + ", in:\n"
                              + method.codeToString(),
                          pc,
                          next.address);
                    }
                    pc += instruction.getSize();
                  }
                })
            .writeToZip();

    testForD8(parameters.getBackend())
        .addProgramFiles(out)
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(o -> o.testing.forceJumboStringProcessing = true)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  static class TestClass {

    // Use synchronized which will require prolog and epilog of monitor instructions.
    // These have small sizes and debug event entries which hit a PC between instructions showing
    // that the event stream is built incorrectly when processing jumbo strings.
    public static synchronized void main(String[] args) {
      System.out.println("Hello world!");
    }
  }
}
