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

import com.android.tools.r8.jasmin.JasminBuilder;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;

/**
 * Regression test to ensure that an incomplete phi creation cannot introduce a local before the
 * locals actual start. The recursive read-register in IRBuilder did not previously account for the
 * change in blocks when determining the local information of the incomplete phi.
 */
public class NoLocalForPhiDebugTest extends DebugTestBase {

  private static final String className = "NoLocalForPhi";
  private static final String sourcefile = className + ".j";
  private static final String methodName = "test";

  @Test
  public void testCf() throws Throwable {
    JasminBuilder builder = getBuilderForUselessCheckcast(className, methodName);
    Path outdir = temp.newFolder().toPath();
    builder.writeClassFiles(outdir);
    CfDebugTestConfig config = new CfDebugTestConfig();
    config.addPaths(outdir);
    run(config);
  }

  @Test
  public void testD8() throws Throwable {
    JasminBuilder builder = getBuilderForUselessCheckcast(className, methodName);
    List<Path> outputs = builder.writeClassFiles(temp.newFolder().toPath());
    run(new D8DebugTestConfig().compileAndAdd(temp, outputs));
  }

  private void run(DebugTestConfig config) throws Throwable {
    runDebugTest(
        config,
        className,
        breakpoint(className, methodName),
        run(),
        checkLine(sourcefile, 1),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 2),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 3),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 4),
        checkLocal("arg"),
        checkLocal("local"),
        // local == 0 => branch to line 5
        stepOver(),
        checkLine(sourcefile, 5),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 2),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 3),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 4),
        checkLocal("arg"),
        checkLocal("local"),
        // local == -1 => branch to line 6 then 7
        stepOver(),
        checkLine(sourcefile, 6),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 7),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 2),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 3),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 4),
        checkLocal("arg"),
        checkLocal("local"),
        // local == 1 => branch to line 6 then 8
        stepOver(),
        checkLine(sourcefile, 6),
        checkLocal("arg"),
        checkNoLocal("local"),
        stepOver(),
        checkLine(sourcefile, 8),
        checkLocal("arg"),
        checkNoLocal("local"),
        run());
  }

  private JasminBuilder getBuilderForUselessCheckcast(String testClassName, String testMethodName) {
    JasminBuilder builder = new JasminBuilder();
    JasminBuilder.ClassBuilder clazz = builder.addClass(testClassName);

    clazz.addStaticMethod(testMethodName, ImmutableList.of("Ljava/lang/Object;"), "V",
        ".limit stack 2",
        ".limit locals 2",
        ".var 0 is arg Ljava/lang/Object; from L_init to L_end",
        ".var 1 is local I from L_local_start to L_local_end",
        "L_init:",
        ".line 1",
        "  ldc 0",
        "  istore 1",

        "L_join:", // A phi flowing to 'local' starts here.
        ".line 2",
        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
        ".line 3", // An intermediate instruction to ensure the phi did not start the local.
        "  nop",

        "L_local_start:", // Delayed start of local.
        ".line 4",
        "  iload 1",
        "  invokevirtual java/io/PrintStream/println(I)V",
        "  iload 1",
        "  ifne L_b2",
        "L_local_end:", // End of local (could also just end at exit).

        "L_b1:",
        ".line 5",
        "  ldc -1",
        "  istore 1",
        "  goto L_join", // Back branch to ensure an incomplete phi is created in L_join.

        "L_b2:",
        ".line 6",
        "  iload 1",
        "  ifgt L_b3",

        ".line 7",
        "  ldc 1",
        "  istore 1",
        "  goto L_join", // Back branch to ensure an incomplete phi is created in L_join.

        "L_b3:",
        ".line 8",
        "return",
        "L_end:");

    clazz.addMainMethod(
        ".limit stack 2",
        ".limit locals 1",
        "aconst_null",
        "invokestatic " + testClassName + "/" + testMethodName + "(Ljava/lang/Object;)V",
        "return");

    return builder;
  }
}
