/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

public class Main {
  public static String smallString = generateString(100);
  public static String mediumString = generateString(300);
  public static String largeString = generateString(2000);

  public static String generateString(int length) {
    // Generate a string in the ASCII range that will
    // use string compression.
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
      // Generate repeating alphabet.
      sb.append(Character.valueOf((char)('a' + (i % 26))));
    }
    return sb.toString();
  }

  public static void assertIntEquals(int expected, int result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertBooleanEquals(boolean expected, boolean result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertCharEquals(char expected, char result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertStringEquals(String expected, String result) {
    if (!expected.equals(result)) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertStringContains(String searchTerm, String result) {
    if (result == null || !result.contains(searchTerm)) {
      throw new Error("Search term: " + searchTerm + ", not found in: " + result);
    }
  }

  public static void main(String[] args) {
    stringEqualsSame();
    stringArgumentNotNull("Foo");

    assertIntEquals(0, $opt$noinline$getStringLength(""));
    assertIntEquals(3, $opt$noinline$getStringLength("abc"));
    assertIntEquals(10, $opt$noinline$getStringLength("0123456789"));

    assertBooleanEquals(true, $opt$noinline$isStringEmpty(""));
    assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc"));
    assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789"));

    assertCharEquals('a', $opt$noinline$stringCharAt("a", 0));
    assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0));
    assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1));
    assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2));
    assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7));

    // Single character.
    assertStringEquals("a", stringGetCharsAndBack("a"));
    // Strings < 8 characters.
    assertStringEquals("foobar", stringGetCharsAndBack("foobar"));
    // Strings > 8 characters of various lengths.
    assertStringEquals(smallString, stringGetCharsAndBack(smallString));
    assertStringEquals(mediumString, stringGetCharsAndBack(mediumString));
    assertStringEquals(largeString, stringGetCharsAndBack(largeString));

    // Get only a substring:
    // Substring < 8 characters.
    assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 0));
    // Substring > 8 characters.
    assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 0));

    // Get full string with offset in the char array.
    assertStringEquals(smallString, stringGetCharsAndBackOffset(smallString, 17));

    // Get a substring with an offset in the char array.
    // Substring < 8 characters.
    assertStringEquals(smallString.substring(5, 10), stringGetCharsRange(smallString, 5, 10, 17));
    // Substring > 8 characters.
    assertStringEquals(smallString.substring(7, 28), stringGetCharsRange(smallString, 7, 28, 17));

    try {
      $opt$noinline$stringCharAt("abc", -1);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }
    try {
      $opt$noinline$stringCharAt("abc", 3);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }
    try {
      $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
    }

    assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7));
    assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10));

    assertCharEquals('7', $opt$noinline$stringCharAtCatchPhiReturn("0123456789", 7));
    assertCharEquals('\0', $opt$noinline$stringCharAtCatchPhiReturn("0123456789", 10));

    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc"));
    assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3));
    try {
      $opt$noinline$stringSumLeadingChars("abcdef", 7);
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringSumLeadingChars",
                           sioob.getStackTrace()[1].toString());
    }
    assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef"));
    try {
      $opt$noinline$stringSum4LeadingChars("abc");
      throw new Error("Should throw SIOOB.");
    } catch (StringIndexOutOfBoundsException sioob) {
      assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
      assertStringContains("Main.$opt$noinline$stringSum4LeadingChars",
                           sioob.getStackTrace()[1].toString());
    }
  }

  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) builder (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:                    Return [<<Length>>]

  /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  static public int $opt$noinline$getStringLength(String s) {
    return s.length();
  }

  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) builder (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<IsEmpty:z\d+>>  Equal [<<Length>>,<<Const0>>]
  /// CHECK-DAG:                    Return [<<IsEmpty>>]

  /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  static public boolean $opt$noinline$isStringEmpty(String s) {
    return s.isEmpty();
  }

  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) builder (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
  /// CHECK-DAG:                    Return [<<Char>>]

  /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  static public char $opt$noinline$stringCharAt(String s, int pos) {
    return s.charAt(pos);
  }

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) builder (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
  /// CHECK-DAG:                    Return [{{(c|i)\d+}}]

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  static public char $opt$noinline$stringCharAtCatch(String s, int pos) {
    try {
      return s.charAt(pos);
    } catch (StringIndexOutOfBoundsException ignored) {
      return '\0';
    }
  }

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatchPhiReturn(java.lang.String, int) builder (after)
  /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
  /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
  /// CHECK-DAG:  <<Int:i\d+>>      IntConstant 0
  /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
  /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
  /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
  /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
  /// CHECK-DAG:  <<Phi:i\d+>>      Phi [<<Char>>,<<Int>>]
  /// CHECK-DAG:                    Return [<<Phi>>]

  /// CHECK-START: char Main.$opt$noinline$stringCharAtCatchPhiReturn(java.lang.String, int) instruction_simplifier (after)
  /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt

  static public char $opt$noinline$stringCharAtCatchPhiReturn(String s, int pos) {
    char result;
    try {
      result = s.charAt(pos);
    } catch (StringIndexOutOfBoundsException ignored) {
      result = '\0';
    }
    return result;
  }

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) builder (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-NOT:                    ArrayLength is_string_length:true

  /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after)
  /// CHECK-NOT:                    BoundsCheck

  static public int $opt$noinline$stringSumChars(String s) {
    int sum = 0;
    int len = s.length();
    for (int i = 0; i < len; ++i) {
      sum += s.charAt(i);
    }
    return sum;
  }

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) builder (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]

  /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true

  static public int $opt$noinline$stringSumLeadingChars(String s, int n) {
    int sum = 0;
    for (int i = 0; i < n; ++i) {
      sum += s.charAt(i);
    }
    return sum;
  }

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) builder (after)
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true
  /// CHECK-DAG:                    ArrayLength is_string_length:true
  /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
  /// CHECK-DAG:                    ArrayGet is_string_char_at:true

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) builder (after)
  /// CHECK-NOT:                    InvokeVirtual

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
  /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]

  /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
  /// CHECK-NOT:                    BoundsCheck is_string_char_at:true

  static public int $opt$noinline$stringSum4LeadingChars(String s) {
    int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3);
    return sum;
  }

  /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before)
  /// CHECK:      InvokeStaticOrDirect

  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
  /// CHECK:      <<Const1:i\d+>> IntConstant 1
  /// CHECK:      Return [<<Const1>>]

  /// CHECK-START: boolean Main.stringEqualsSame() register (before)
  /// CHECK-NOT:  InvokeStaticOrDirect
  public static boolean stringEqualsSame() {
    return $inline$callStringEquals("obj", "obj");
  }

  /// CHECK-START: boolean Main.stringEqualsNull() register (after)
  /// CHECK:      <<Invoke:z\d+>> InvokeVirtual
  /// CHECK:      Return [<<Invoke>>]
  public static boolean stringEqualsNull() {
    String o = (String)myObject;
    return $inline$callStringEquals(o, o);
  }

  public static boolean $inline$callStringEquals(String a, String b) {
    return a.equals(b);
  }

  /// CHECK-START-X86: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      test

  /// CHECK-START-X86_64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      test

  /// CHECK-START-ARM: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  // CompareAndBranchIfZero() may emit either CBZ or CMP+BEQ.
  /// CHECK-NOT:      cbz
  /// CHECK-NOT:      cmp {{r\d+}}, #0
  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
  // whichever comes first.
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}

  /// CHECK-START-ARM64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
  /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
  /// CHECK-NOT:      cbz
  // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
  // whichever comes first.
  /// CHECK:          cmp {{w.*,}} {{w.*|#.*}}
  public static boolean stringArgumentNotNull(Object obj) {
    obj.getClass();
    return "foo".equals(obj);
  }

  // Test is very brittle as it depends on the order we emit instructions.
  /// CHECK-START-X86: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          test
  /// CHECK:          jz/eq
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      mov
  /// CHECK:          cmp

  // Test is very brittle as it depends on the order we emit instructions.
  /// CHECK-START-X86_64: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          test
  /// CHECK:          jz/eq
  // Check that we don't try to compare the classes.
  /// CHECK-NOT:      mov
  /// CHECK:          cmp

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-ARM: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          {{cbz|cmp}}
  // Check that we don't try to compare the classes.
  // The dissassembler currently explicitly emits the offset 0 but don't rely on it.
  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
  // equality and one for length comparison but these may be emitted in different order,
  // so repeat the check twice.
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
  /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
  /// CHECK:          cmp {{r\d+}}, {{r\d+}}

  // Test is brittle as it depends on the class offset being 0.
  /// CHECK-START-ARM64: boolean Main.stringArgumentIsString() disassembly (after)
  /// CHECK:          InvokeVirtual intrinsic:StringEquals
  /// CHECK:          cbz
  // Check that we don't try to compare the classes.
  // The dissassembler currently does not explicitly emits the offset 0 but don't rely on it.
  // We want to terminate the CHECK-NOT search after two CMPs, one for reference
  // equality and one for length comparison but these may be emitted in different order,
  // so repeat the check twice.
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
  /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
  /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
  public static boolean stringArgumentIsString() {
    return "foo".equals(myString);
  }

  static String myString;
  static Object myObject;

  public static String stringGetCharsAndBack(String src) {
    char[] dst = new char[src.length()];
    src.getChars(0, src.length(), dst, 0);
    return new String(dst);
  }

  public static String stringGetCharsAndBackOffset(String src, int offset) {
    char[] dst = new char[src.length() + offset];
    src.getChars(0, src.length(), dst, offset);
    return new String(dst, offset, src.length());
  }

  public static String stringGetCharsRange(String src, int srcBegin, int srcEnd, int offset) {
    char[] dst = new char[srcEnd - srcBegin + offset];
    src.getChars(srcBegin, srcEnd, dst, offset);
    return new String(dst, offset, srcEnd - srcBegin);
  }
}
