// 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.ToolHelper;
import com.android.tools.r8.utils.AndroidApp;
import org.junit.Test;

public class LocalsInSwitchTestRunner extends DebugInfoTestBase {

  @Test
  public void testLocalsInSwitch() throws Exception {
    Class clazz = LocalsInSwitchTest.class;

    AndroidApp d8App = compileWithD8(clazz);

    String expected = "55" + ToolHelper.LINE_SEPARATOR + "1862" + ToolHelper.LINE_SEPARATOR
            + "15130" + ToolHelper.LINE_SEPARATOR;
    assertEquals(expected, runOnJava(clazz));
    assertEquals(expected, runOnArt(d8App, clazz.getCanonicalName()));

    checkNoLocals(inspectMethod(d8App, clazz, "int", "noLocals", "int"));

    checkTempInCase(inspectMethod(d8App, clazz, "int", "tempInCase", "int"));

    checkInitInCases(inspectMethod(d8App, clazz, "int", "initInCases", "int"));
  }

  private void checkNoLocals(DebugInfoInspector info) {
    info.checkStartLine(9);
    info.checkLineHasExactLocals(9, "x", "int");
    info.checkLineHasExactLocals(11, "x", "int");
    info.checkLineHasExactLocals(13, "x", "int");
    info.checkLineHasExactLocals(15, "x", "int");
  }

  private void checkTempInCase(DebugInfoInspector tempInCase) {
    // int res =
    tempInCase.checkStartLine(20);
    tempInCase.checkLineHasExactLocals(20, "x", "int");
    // for (int i = ...
    // The local 'i' is visible on the back edges, but not on the initial entry.
    tempInCase.checkLineHasAtLeastLocals(21, "x", "int", "res", "int");
    //   int rem =
    tempInCase.checkLineHasExactLocals(22, "x", "int", "res", "int", "i", "int");
    //   switch (rem) {
    tempInCase.checkLineHasExactLocals(23, "x", "int", "res", "int", "i", "int", "rem", "int");
    //   case 0:
    tempInCase.checkNoLine(24);
    //     return res
    tempInCase.checkLineHasExactLocals(25, "x", "int", "res", "int", "i", "int", "rem", "int");
    //   case 5:
    tempInCase.checkNoLine(26);
    //     int tmp =
    tempInCase.checkLineHasExactLocals(27, "x", "int", "res", "int", "i", "int", "rem", "int");
    //     res += tmp
    tempInCase.checkLineHasExactLocals(28,
        "x", "int", "res", "int", "i", "int", "rem", "int", "tmp", "int");
    //     break;
    tempInCase.checkLineHasExactLocals(29,
        "x", "int", "res", "int", "i", "int", "rem", "int", "tmp", "int");
    //   case 10:
    tempInCase.checkNoLine(30);
    //     i++
    tempInCase.checkLineHasExactLocals(31, "x", "int", "res", "int", "i", "int", "rem", "int");
    //     break;
    tempInCase.checkLineHasExactLocals(32, "x", "int", "res", "int", "i", "int", "rem", "int");
    //   default:
    tempInCase.checkNoLine(33);
    //     res += rem;
    tempInCase.checkLineHasExactLocals(34, "x", "int", "res", "int", "i", "int", "rem", "int");
    //   }
    tempInCase.checkNoLine(35);
    //   res += rem % 2;
    tempInCase.checkLineHasExactLocals(36, "x", "int", "res", "int", "i", "int", "rem", "int");
    // }
    tempInCase.checkNoLine(37);
    // res *= x;
    tempInCase.checkLineHasExactLocals(38, "x", "int", "res", "int");
    // return res;
    tempInCase.checkLineHasExactLocals(39, "x", "int", "res", "int");
  }

  private void checkInitInCases(DebugInfoInspector info) {
    info.checkNoLine(43); // No line on uninitialized local declaration.
    info.checkStartLine(44);
    info.checkLineHasExactLocals(44, "x", "int"); // Local "res" is still not visible in the case.
    info.checkLineHasExactLocals(46, "x", "int"); // Ditto.
    info.checkLineHasExactLocals(48, "x", "int"); // Ditto.
    info.checkLineHasExactLocals(51, "x", "int"); // Ditto.
    info.checkLineHasExactLocals(53, "x", "int", "res", "java.lang.Integer");
  }
}
