// 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.
// Dart core library.

// VM implementation of int.

@patch
class int {
  @patch
  const factory int.fromEnvironment(String name, {int defaultValue})
      native "Integer_fromEnvironment";

  static int _tryParseSmi(String str, int first, int last) {
    assert(first <= last);
    var ix = first;
    var sign = 1;
    var c = str.codeUnitAt(ix);
    // Check for leading '+' or '-'.
    if ((c == 0x2b) || (c == 0x2d)) {
      ix++;
      sign = 0x2c - c; // -1 for '-', +1 for '+'.
      if (ix > last) {
        return null; // Empty.
      }
    }
    var smiLimit = internal.is64Bit ? 18 : 9;
    if ((last - ix) >= smiLimit) {
      return null; // May not fit into a Smi.
    }
    var result = 0;
    for (int i = ix; i <= last; i++) {
      var c = 0x30 ^ str.codeUnitAt(i);
      if (9 < c) {
        return null;
      }
      result = 10 * result + c;
    }
    return sign * result;
  }

  @patch
  static int parse(String source, {int radix, int onError(String source)}) {
    if (source == null) throw new ArgumentError("The source must not be null");
    if (source.isEmpty) return _throwFormatException(onError, source, 0, radix);
    if (radix == null || radix == 10) {
      // Try parsing immediately, without trimming whitespace.
      int result = _tryParseSmi(source, 0, source.length - 1);
      if (result != null) return result;
    } else if (radix < 2 || radix > 36) {
      throw new RangeError("Radix $radix not in range 2..36");
    }
    // Split here so improve odds of parse being inlined and the checks omitted.
    return _parse(source, radix, onError);
  }

  static int _parse(String source, int radix, onError) {
    int end = source._lastNonWhitespace() + 1;
    if (end == 0) {
      return _throwFormatException(onError, source, source.length, radix);
    }
    int start = source._firstNonWhitespace();

    int first = source.codeUnitAt(start);
    int sign = 1;
    if (first == 0x2b /* + */ || first == 0x2d /* - */) {
      sign = 0x2c - first; // -1 if '-', +1 if '+'.
      start++;
      if (start == end) {
        return _throwFormatException(onError, source, end, radix);
      }
      first = source.codeUnitAt(start);
    }
    if (radix == null) {
      // check for 0x prefix.
      int index = start;
      if (first == 0x30 /* 0 */) {
        index++;
        if (index == end) return 0;
        first = source.codeUnitAt(index);
        if ((first | 0x20) == 0x78 /* x */) {
          index++;
          if (index == end) {
            return _throwFormatException(onError, source, index, null);
          }
          int result = _parseRadix(source, 16, index, end, sign);
          if (result == null) {
            return _throwFormatException(onError, source, null, null);
          }
          return result;
        }
      }
      radix = 10;
    }
    int result = _parseRadix(source, radix, start, end, sign);
    if (result == null) {
      return _throwFormatException(onError, source, null, radix);
    }
    return result;
  }

  static int _throwFormatException(onError, source, index, radix) {
    if (onError != null) return onError(source);
    if (radix == null) {
      throw new FormatException("Invalid number", source, index);
    }
    throw new FormatException("Invalid radix-$radix number", source, index);
  }

  static int _parseRadix(
      String source, int radix, int start, int end, int sign) {
    int tableIndex = (radix - 2) * 4 + (internal.is64Bit ? 2 : 0);
    int blockSize = _PARSE_LIMITS[tableIndex];
    int length = end - start;
    if (length <= blockSize) {
      _Smi smi = _parseBlock(source, radix, start, end);
      if (smi != null) return sign * smi;
      return null;
    }

    // Often cheaper than: int smallBlockSize = length % blockSize;
    // because digit count generally tends towards smaller. rather
    // than larger.
    int smallBlockSize = length;
    while (smallBlockSize >= blockSize) smallBlockSize -= blockSize;
    int result = 0;
    if (smallBlockSize > 0) {
      int blockEnd = start + smallBlockSize;
      _Smi smi = _parseBlock(source, radix, start, blockEnd);
      if (smi == null) return null;
      result = sign * smi;
      start = blockEnd;
    }
    int multiplier = _PARSE_LIMITS[tableIndex + 1];
    int blockEnd = start + blockSize;
    do {
      _Smi smi = _parseBlock(source, radix, start, blockEnd);
      if (smi == null) return null;
      result = (result * multiplier) + (sign * smi);
      start = blockEnd;
      blockEnd = start + blockSize;
    } while (blockEnd <= end);
    return result;
  }

  // Parse block of digits into a Smi.
  static _Smi _parseBlock(String source, int radix, int start, int end) {
    _Smi result = 0;
    if (radix <= 10) {
      for (int i = start; i < end; i++) {
        int digit = source.codeUnitAt(i) ^ 0x30;
        if (digit >= radix) return null;
        result = radix * result + digit;
      }
    } else {
      for (int i = start; i < end; i++) {
        int char = source.codeUnitAt(i);
        int digit = char ^ 0x30;
        if (digit > 9) {
          digit = (char | 0x20) - (0x61 - 10);
          if (digit < 10 || digit >= radix) return null;
        }
        result = radix * result + digit;
      }
    }
    return result;
  }

  // For each radix, 2-36, how many digits are guaranteed to fit in a smi,
  // and magnitude of such a block (radix ** digit-count).
  // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2
  static const _PARSE_LIMITS = const [
    30, 1073741824, 62, 4611686018427387904, // radix: 2
    18, 387420489, 39, 4052555153018976267,
    15, 1073741824, 30, 1152921504606846976,
    12, 244140625, 26, 1490116119384765625, //  radix: 5
    11, 362797056, 23, 789730223053602816,
    10, 282475249, 22, 3909821048582988049,
    10, 1073741824, 20, 1152921504606846976,
    9, 387420489, 19, 1350851717672992089,
    9, 1000000000, 18, 1000000000000000000, //  radix: 10
    8, 214358881, 17, 505447028499293771,
    8, 429981696, 17, 2218611106740436992,
    8, 815730721, 16, 665416609183179841,
    7, 105413504, 16, 2177953337809371136,
    7, 170859375, 15, 437893890380859375, //    radix: 15
    7, 268435456, 15, 1152921504606846976,
    7, 410338673, 15, 2862423051509815793,
    7, 612220032, 14, 374813367582081024,
    7, 893871739, 14, 799006685782884121,
    6, 64000000, 14, 1638400000000000000, //    radix: 20
    6, 85766121, 14, 3243919932521508681,
    6, 113379904, 13, 282810057883082752,
    6, 148035889, 13, 504036361936467383,
    6, 191102976, 13, 876488338465357824,
    6, 244140625, 13, 1490116119384765625, //   radix: 25
    6, 308915776, 13, 2481152873203736576,
    6, 387420489, 13, 4052555153018976267,
    6, 481890304, 12, 232218265089212416,
    6, 594823321, 12, 353814783205469041,
    6, 729000000, 12, 531441000000000000, //    radix: 30
    6, 887503681, 12, 787662783788549761,
    6, 1073741824, 12, 1152921504606846976,
    5, 39135393, 12, 1667889514952984961,
    5, 45435424, 12, 2386420683693101056,
    5, 52521875, 12, 3379220508056640625, //    radix: 35
    5, 60466176, 11, 131621703842267136,
  ];
}
