// 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.
// @dart=2.9

part of 'number_format.dart';

// 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
///
///       _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,
      int decimalDigits,
      bool lookupSimpleCurrencySymbol = false,
      bool isForCurrency = false})
      : super._forPattern(locale, getPattern,
            name: name,
            currencySymbol: currencySymbol,
            decimalDigits: decimalDigits,
            lookupSimpleCurrencySymbol: lookupSimpleCurrencySymbol,
            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);
    final divisor = _style.printsAsIs ? 1 : _style.divisor;
    final 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);
    }
    final 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) {
    final 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);
    }
  }

  /// Defines minimumFractionDigits based on current style being formatted.
  @override
  int get minimumFractionDigits {
    if (!_isForCurrency ||
        !significantDigitsInUse ||
        _style == null ||
        _style.isFallback) {
      return super.minimumFractionDigits;
    } else {
      return 0;
    }
  }

  /// 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];
}
