// Copyright (c) 2016, 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.

part of intl;

// Suppress naming issues as changes would be breaking.
// ignore_for_file: constant_identifier_names

/// An abstract class for compact number styles.
abstract class _CompactStyleBase {
  /// The _CompactStyle for the sign of [number], i.e. positive or
  /// negative.
  _CompactStyle styleForSign(number);

  /// How many total digits do we expect in the number.
  ///
  /// If the pattern is
  ///
  ///       4: '00K',
  ///
  /// then this is 5, meaning we expect this to be a 5-digit (or more)
  /// number. We will scale by 1000 and expect 2 integer digits remaining, so we
  /// get something like '12K'. This is used to find the closest pattern for a
  /// number.
  int get totalDigits;

  /// What should we divide the number by in order to print. Normally it is
  /// either `10^normalizedExponent` or 1 if we shouldn't divide at all.
  int get divisor;

  /// The iterable of all possible styles which we represent.
  ///
  /// Normally this will be either a list with just ourself, or of two elements
  /// for our positive and negative styles.
  Iterable<_CompactStyle> get allStyles;
}

/// A compact format with separate styles for positive and negative numbers.
class _CompactStyleWithNegative extends _CompactStyleBase {
  _CompactStyleWithNegative(this.positiveStyle, this.negativeStyle);
  final _CompactStyle positiveStyle;
  final _CompactStyle negativeStyle;
  _CompactStyle styleForSign(number) =>
      number < 0 ? negativeStyle : positiveStyle;
  int get totalDigits => positiveStyle.totalDigits;
  int get divisor => positiveStyle.divisor;
  List<_CompactStyle> get allStyles => [positiveStyle, negativeStyle];
}

/// Represents a compact format for a particular base
///
/// For example, 10K can be used to represent 10,000.  Corresponds to one of the
/// patterns in COMPACT_DECIMAL_SHORT_FORMAT. So, for example, in en_US we have
/// the pattern
///
///       4: '00K'
/// which matches
///
///      new _CompactStyle(pattern: '00K', normalizedExponent: 4, divisor: 1000,
///      expectedDigits: 1, prefix: '', suffix: 'K');
///
/// where expectedDigits is the number of zeros.
class _CompactStyle extends _CompactStyleBase {
  _CompactStyle(
      {this.pattern,
      this.normalizedExponent = 0,
      this.divisor = 1,
      this.expectedDigits = 1,
      this.prefix = '',
      this.suffix = ''});

  /// The pattern on which this is based.
  ///
  /// We don't actually need this, but it makes debugging easier.
  String pattern;

  /// The normalized scientific notation exponent for which the format applies.
  ///
  /// So if this is 3, we expect it to apply for numbers from 1000 and up.
  /// Typically it would be from 1000 to 9999, but that depends if there's a
  /// style for 4 or not. This is the CLDR index of the pattern, and usually
  /// determines the divisor, but if the pattern is just a 0 with no prefix or
  /// suffix then we don't divide at all.
  int normalizedExponent;

  /// What should we divide the number by in order to print. Normally is either
  /// 10^normalizedExponent or 1 if we shouldn't divide at all.
  int divisor;

  /// How many integer digits do we expect to print - the number of zeros in the
  /// CLDR pattern.
  int expectedDigits;

  /// Text we put in front of the number part.
  String prefix;

  /// Text we put after the number part.
  String suffix;

  /// How many total digits do we expect in the number.
  ///
  /// If the pattern is
  ///
  ///       4: '00K',
  ///
  /// then this is 5, meaning we expect this to be a 5-digit (or more)
  /// number. We will scale by 1000 and expect 2 integer digits remaining, so we
  /// get something like '12K'. This is used to find the closest pattern for a
  /// number.
  int get totalDigits => normalizedExponent + expectedDigits - 1;

  /// Return true if this is the fallback compact pattern, printing the number
  /// un-compacted. e.g. 1200 might print as '1.2K', but 12 just prints as '12'.
  ///
  /// For currencies, with the fallback pattern we use the super implementation
  /// so that we will respect things like the default number of decimal digits
  /// for a particular currency (e.g. two for USD, zero for JPY)
  bool get isFallback => pattern == null || pattern == '0';

  /// Should we print the number as-is, without dividing.
  ///
  /// This happens if the pattern has no abbreviation for scaling (e.g. K, M).
  /// So either the pattern is empty or it is of a form like '0 $'. This is a
  /// workaround for locales like 'it', which include patterns with no suffix
  /// for numbers >= 1000 but < 1,000,000.
  bool get printsAsIs =>
      isFallback || pattern.replaceAll(RegExp('[0\u00a0\u00a4]'), '').isEmpty;

  _CompactStyle styleForSign(number) => this;
  List<_CompactStyle> get allStyles => [this];
}

/// Enumerates the different formats supported.
enum _CompactFormatType {
  COMPACT_DECIMAL_SHORT_PATTERN,
  COMPACT_DECIMAL_LONG_PATTERN,
  COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN
}

class _CompactNumberFormat extends NumberFormat {
  /// A default, using the decimal pattern, for the `getPattern` constructor parameter.
  static String _forDecimal(NumberSymbols symbols) => symbols.DECIMAL_PATTERN;

  List<_CompactStyleBase> _styles = [];

  _CompactNumberFormat(
      {String locale,
      _CompactFormatType formatType,
      String name,
      String currencySymbol,
      String Function(NumberSymbols) getPattern = _forDecimal,
      String Function(NumberFormat) computeCurrencySymbol,
      int decimalDigits,
      bool isForCurrency = false})
      : super._forPattern(locale, getPattern,
            name: name,
            currencySymbol: currencySymbol,
            computeCurrencySymbol: computeCurrencySymbol,
            decimalDigits: decimalDigits,
            isForCurrency: isForCurrency) {
    significantDigits = 3;
    turnOffGrouping();

    /// Map from magnitude to formatting pattern for that magnitude.
    ///
    /// The magnitude is the exponent when using the normalized scientific
    /// notation (so numbers from 1000 to 9999 correspond to magnitude 3).
    ///
    /// These patterns are taken from the appropriate CompactNumberSymbols
    /// instance's COMPACT_DECIMAL_SHORT_PATTERN, COMPACT_DECIMAL_LONG_PATTERN,
    /// or COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN members.
    Map<int, String> _patterns;

    switch (formatType) {
      case _CompactFormatType.COMPACT_DECIMAL_SHORT_PATTERN:
        _patterns = _compactSymbols.COMPACT_DECIMAL_SHORT_PATTERN;
        break;
      // TODO(alanknight): Long formats may have different forms for different
      // plural cases (e.g. million/millions).
      case _CompactFormatType.COMPACT_DECIMAL_LONG_PATTERN:
        _patterns = _compactSymbols.COMPACT_DECIMAL_LONG_PATTERN ??
            _compactSymbols.COMPACT_DECIMAL_SHORT_PATTERN;
        break;
      case _CompactFormatType.COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN:
        _patterns = _compactSymbols.COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN;
        break;
      default:
        throw ArgumentError.notNull('formatType');
    }
    _patterns.forEach((int exponent, String pattern) {
      if (pattern.contains(';')) {
        var patterns = pattern.split(';');
        _styles.add(_CompactStyleWithNegative(
            _createStyle(patterns.first, exponent),
            _createStyle(patterns.last, exponent)));
      } else {
        _styles.add(_createStyle(pattern, exponent));
      }
    });

    // Reverse the styles so that we look through them from largest to smallest.
    _styles = _styles.reversed.toList();
    // Add a fallback style that just prints the number.
    _styles.add(_CompactStyle());
  }

  final _regex = RegExp('([^0]*)(0+)(.*)');

  final _justZeros = RegExp(r'^0*$');

  /// Does pattern have any additional characters or is it just zeros.
  bool _hasNonZeroContent(String pattern) => !_justZeros.hasMatch(pattern);

  /// Creates a [_CompactStyle] instance for pattern with [normalizedExponent].
  _CompactStyle _createStyle(String pattern, int normalizedExponent) {
    var match = _regex.firstMatch(pattern);
    var integerDigits = match.group(2).length;
    var prefix = match.group(1);
    var suffix = match.group(3);
    // If the pattern is just zeros, with no suffix, then we shouldn't divide
    // by the number of digits. e.g. for 'af', the pattern for 3 is '0', but
    // it doesn't mean that 4321 should print as 4. But if the pattern was
    // '0K', then it should print as '4K'. So we have to check if the pattern
    // has a suffix. This seems extremely hacky, but I don't know how else to
    // encode that. Check what other things are doing.
    var divisor = 1;
    if (_hasNonZeroContent(pattern)) {
      divisor = pow(10, normalizedExponent - integerDigits + 1);
    }
    return _CompactStyle(
        pattern: pattern,
        normalizedExponent: normalizedExponent,
        expectedDigits: integerDigits,
        prefix: prefix,
        suffix: suffix,
        divisor: divisor);
  }

  /// The style in which we will format a particular number.
  ///
  /// This is a temporary variable that is only valid within a call to format.
  _CompactStyle _style;

  String format(number) {
    _style = _styleFor(number);
    var divisor = _style.printsAsIs ? 1 : _style.divisor;
    var numberToFormat = _divide(number, divisor);
    var formatted = super.format(numberToFormat);
    var prefix = _style.prefix;
    var suffix = _style.suffix;
    // If this is for a currency, then the super call will have put the currency
    // somewhere. We don't want it there, we want it where our style indicates,
    // so remove it and replace. This has the remote possibility of a false
    // positive, but it seems unlikely that e.g. USD would occur as a string in
    // a regular number.
    if (_isForCurrency && !_style.isFallback) {
      formatted = formatted.replaceFirst(currencySymbol, '').trim();
      prefix = prefix.replaceFirst('\u00a4', currencySymbol);
      suffix = suffix.replaceFirst('\u00a4', currencySymbol);
    }
    var withExtras = '$prefix$formatted$suffix';
    _style = null;
    return withExtras;
  }

  /// How many digits after the decimal place should we display, given that
  /// there are [remainingSignificantDigits] left to show.
  int _fractionDigitsAfter(int remainingSignificantDigits) {
    var newFractionDigits =
        super._fractionDigitsAfter(remainingSignificantDigits);
    // For non-currencies, or for currencies if the numbers are large enough to
    // compact, always use the number of significant digits and ignore
    // decimalDigits. That is, $1.23K but also ¥12.3\u4E07, even though yen
    // don't normally print decimal places.
    if (!_isForCurrency || !_style.isFallback) return newFractionDigits;
    // If we are printing a currency and it's too small to compact, but
    // significant digits would have us only print some of the decimal digits,
    // use all of them. So $12.30, not $12.3
    if (newFractionDigits > 0 && newFractionDigits < decimalDigits) {
      return decimalDigits;
    } else {
      return min(newFractionDigits, decimalDigits);
    }
  }

  /// Divide numbers that may not have a division operator (e.g. Int64).
  ///
  /// Only used for powers of 10, so we require an integer denominator.
  num _divide(numerator, int denominator) {
    if (numerator is num) {
      return numerator / denominator;
    }
    // If it doesn't fit in a JS int after division, we're not going to be able
    // to meaningfully print a compact representation for it.
    var divided = numerator ~/ denominator;
    var integerPart = divided.toInt();
    if (divided != integerPart) {
      throw FormatException(
          'Number too big to use with compact format', numerator);
    }
    var remainder = numerator.remainder(denominator).toInt();
    var originalFraction = numerator - (numerator ~/ 1);
    var fraction = originalFraction == 0 ? 0 : originalFraction / denominator;
    return integerPart + (remainder / denominator) + fraction;
  }

  _CompactStyle _styleFor(number) {
    // We have to round the number based on the number of significant digits so
    // that we pick the right style based on the rounded form and format 999999
    // as 1M rather than 1000K.
    var originalLength = NumberFormat.numberOfIntegerDigits(number);
    var additionalDigits = originalLength - significantDigits;
    var digitLength = originalLength;
    if (additionalDigits > 0) {
      var divisor = pow(10, additionalDigits);
      // If we have an Int64, value speed over precision and make it double.
      var rounded = (number.toDouble() / divisor).round() * divisor;
      digitLength = NumberFormat.numberOfIntegerDigits(rounded);
    }
    for (var style in _styles) {
      if (digitLength > style.totalDigits) {
        return style.styleForSign(number);
      }
    }
    throw FormatException(
        'No compact style found for number. This should not happen', number);
  }

  Iterable<_CompactStyle> get _stylesForSearching =>
      _styles.reversed.expand((x) => x.allStyles);

  num parse(String text) {
    for (var style in _stylesForSearching) {
      if (text.startsWith(style.prefix) && text.endsWith(style.suffix)) {
        var numberText = text.substring(
            style.prefix.length, text.length - style.suffix.length);
        var number = _tryParsing(numberText);
        if (number != null) {
          return number * style.divisor;
        }
      }
    }
    throw FormatException(
        "Cannot parse compact number in locale '$locale'", text);
  }

  /// Returns text parsed into a number if possible, else returns null.
  num _tryParsing(String text) {
    try {
      return super.parse(text);
    } on FormatException {
      return null;
    }
  }

  /// The [CompactNumberSymbols] instance that corresponds to the [_locale] this
  /// [NumberFormat] instance was configured for.
  CompactNumberSymbols get _compactSymbols => compactNumberSymbols[_locale];
}
