// Copyright (c) 2012, the Dart 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.

import "package:expect/expect.dart";
import "dart:math" show pow;

void main() {
  bool checkedMode = false;
  assert(checkedMode = true);
  const String oneByteWhiteSpace = "\x09\x0a\x0b\x0c\x0d\x20"
    "\x85"    /// 01: ok
    "\xa0";
  const String whiteSpace = "$oneByteWhiteSpace\u1680\u180e"
      "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a"
      "\u2028\u2029\u202f\u205f\u3000\ufeff";

  var digits = "0123456789abcdefghijklmnopqrstuvwxyz";
  var zeros = "0" * 64;

  for (int i = 0; i < whiteSpace.length; i++) {
    var ws = whiteSpace[i];
    print(ws.codeUnitAt(0).toRadixString(16));
    Expect.equals(0, int.parse("${ws}0${ws}", radix: 2));
  }

  void testParse(int result, String radixString, int radix) {
    var m = "$radixString/$radix->$result";
    Expect.equals(result,
                  int.parse(radixString.toLowerCase(), radix: radix), m);
    Expect.equals(result,
                  int.parse(radixString.toUpperCase(), radix: radix), m);
    Expect.equals(result, int.parse(" $radixString", radix: radix), m);
    Expect.equals(result, int.parse("$radixString ", radix: radix), m);
    Expect.equals(result, int.parse(" $radixString ", radix: radix), m);
    Expect.equals(result, int.parse("+$radixString", radix: radix), m);
    Expect.equals(result, int.parse(" +$radixString", radix: radix), m);
    Expect.equals(result, int.parse("+$radixString ", radix: radix), m);
    Expect.equals(result, int.parse(" +$radixString ", radix: radix), m);
    Expect.equals(-result, int.parse("-$radixString", radix: radix), m);
    Expect.equals(-result, int.parse(" -$radixString", radix: radix), m);
    Expect.equals(-result, int.parse("-$radixString ", radix: radix), m);
    Expect.equals(-result, int.parse(" -$radixString ", radix: radix), m);
    Expect.equals(result, int.parse(
        "$oneByteWhiteSpace$radixString$oneByteWhiteSpace", radix: radix), m);
    Expect.equals(-result, int.parse(
        "$oneByteWhiteSpace-$radixString$oneByteWhiteSpace", radix: radix), m);
    Expect.equals(result, int.parse(
        "$whiteSpace$radixString$whiteSpace", radix: radix), m);
    Expect.equals(-result, int.parse(
        "$whiteSpace-$radixString$whiteSpace", radix: radix), m);

    Expect.equals(result, int.parse("$zeros$radixString", radix: radix), m);
    Expect.equals(result, int.parse("+$zeros$radixString", radix: radix), m);
    Expect.equals(-result, int.parse("-$zeros$radixString", radix: radix), m);
  }

  for (int i = 0; i <= 36 * 36; i++) {
    for (int r = 2; r <= 36; r++) {
      String radixString = i.toRadixString(r);
      testParse(i, radixString, r);
    }
  }

  for (int i = 2; i <= 36; i++) {              /// 02: ok
    // Test with bignums.                      /// 02: continued
    var digit = digits[i - 1];                 /// 02: continued
    testParse(pow(i, 64) - 1, digit * 64, i);  /// 02: continued
    testParse(0, zeros, i);                    /// 02: continued
  }                                            /// 02: continued

  // Allow both upper- and lower-case letters.
  Expect.equals(0xABCD, int.parse("ABCD", radix: 16));
  Expect.equals(0xABCD, int.parse("abcd", radix: 16));
  Expect.equals(15628859, int.parse("09azAZ", radix: 36));
  // Big number.
  Expect.equals(0x12345678123456781234567812345678,  /// 02: continued
                int.parse("0x1234567812345678"       /// 02: continued
                          "1234567812345678"));      /// 02: continued
  // Allow whitespace before and after the number.
  Expect.equals(1, int.parse(" 1", radix: 2));
  Expect.equals(1, int.parse("1 ", radix: 2));
  Expect.equals(1, int.parse(" 1 ", radix: 2));
  Expect.equals(1, int.parse("\n1", radix: 2));
  Expect.equals(1, int.parse("1\n", radix: 2));
  Expect.equals(1, int.parse("\n1\n", radix: 2));
  Expect.equals(1, int.parse("+1", radix: 2));

  void testFails(String source, int radix) {
    Expect.throws(() { throw int.parse(source, radix: radix,
                                       onError: (s) { throw "FAIL"; }); },
                  (e) => e == "FAIL",
                  "$source/$radix");
    Expect.equals(-999, int.parse(source, radix: radix, onError: (s) => -999));
  }
  for (int i = 2; i < 36; i++) {
    testFails(i.toRadixString(36).toLowerCase(), i);
    testFails(i.toRadixString(36).toUpperCase(), i);
  }
  testFails("", 2);
  testFails("+ 1", 2);  // No space between sign and digits.
  testFails("- 1", 2);  // No space between sign and digits.
  testFails("0x", null);
  for (int i = 2; i <= 33; i++) {
    // No 0x specially allowed.
    // At radix 34 and above, "x" is a valid digit.
    testFails("0x10", i);
  }

  testBadTypes(var source, var radix) {
    if (!checkedMode) {
      // No promises on what error is thrown if the type doesn't match.
      // Likely either ArgumentError or NoSuchMethodError.
      Expect.throws(() => int.parse(source, radix: radix, onError: (s) => 0));
      return;
    }
    // In checked mode, it's always a TypeError.
    Expect.throws(() => int.parse(source, radix: radix, onError: (s) => 0),
                  (e) => e is TypeError);
  }

  testBadTypes(9, 10);
  testBadTypes(true, 10);
  testBadTypes("0", true);
  testBadTypes("0", "10");

  testBadArguments(String source, int radix) {
    // If the types match, it should be an ArgumentError of some sort.
    Expect.throws(() => int.parse(source, radix: radix, onError: (s) => 0),
                  (e) => e is ArgumentError);
  }

  testBadArguments("0", -1);
  testBadArguments("0", 0);
  testBadArguments("0", 1);
  testBadArguments("0", 37);

  // If handleError isn't an unary function, and it's called, it also throws
  // (either TypeError in checked mode, or some failure in unchecked mode).
  Expect.throws(() => int.parse("9", radix: 8, onError: "not a function"));
  Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
  Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
}
