/// 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

/// Tests for compact format numbers, e.g. 1.2M rather than 1,200,000
import 'dart:math';
import 'package:test/test.dart';
import 'package:intl/intl.dart';
import 'package:fixnum/fixnum.dart';
import 'package:intl/number_symbols_data.dart' as patterns;
import 'compact_number_test_data_33.dart' as testdata33;
// End-goal: to stop testing against testdata33 and use testdata35 instead:
// import 'compact_number_test_data.dart' as testdata35;
import 'more_compact_number_test_data.dart' as more_testdata;

/// A place to put a case that's causing a problem and have it run first when
/// debugging
var interestingCases = <String, List<List<String>>>{
//  'mn' : [['4321', '4.32M', 'whatever']]
};

void main() {
  interestingCases.forEach(validate);
  testdata33.compactNumberTestData.forEach(validate);
  more_testdata.oldIntlCompactNumTests.forEach(validateFancy);
  // Once code and data is updated to CLDR35:
  // testdata35.compactNumberTestData.forEach(validate);
  // more_testdata.cldr35CompactNumTests.forEach(validateFancy);

  test("Patterns are consistent across locales", () {
    patterns.compactNumberSymbols.forEach((locale, patterns) {
      expect(patterns.COMPACT_DECIMAL_SHORT_PATTERN.keys,
          orderedEquals([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]),
          reason: "Precision algorithm expects no gaps in pattern magnitudes");
    });
  });

  // ICU doesn't support compact currencies yet, so we don't have a way to
  // generate automatic data for comparison. Hard-coded a couple of cases as a
  // smoke test. JPY is a useful test because it has no decimalDigits and
  // different grouping than USD, as well as a different currency symbol and
  // suffixes.
  testCurrency('ja', 1.2345, '¥1', '¥1');
  testCurrency('ja', 1, '¥1', '¥1');
  testCurrency('ja', 12, '¥12', '¥10');
  testCurrency('ja', 123, '¥123', '¥100');
  testCurrency('ja', 1234, '¥1230', '¥1000');
  testCurrency('ja', 12345, '¥1.23\u4E07', '¥1\u4E07');
  testCurrency('ja', 123456, '¥12.3\u4E07', '¥10\u4E07');
  testCurrency('ja', 1234567, '¥123\u4e07', '¥100\u4e07');
  testCurrency('ja', 12345678, '¥1230\u4e07', '¥1000\u4e07');
  testCurrency('ja', 123456789, '¥1.23\u5104', '¥1\u5104');

  testCurrency('ja', 0.9876, '¥1', '¥1');
  testCurrency('ja', 9, '¥9', '¥9');
  testCurrency('ja', 98, '¥98', '¥100');
  testCurrency('ja', 987, '¥987', '¥1000');
  testCurrency('ja', 9876, '¥9880', '¥1\u4E07');
  testCurrency('ja', 98765, '¥9.88\u4E07', '¥10\u4E07');
  testCurrency('ja', 987656, '¥98.8\u4E07', '¥100\u4E07');
  testCurrency('ja', 9876567, '¥988\u4e07', '¥1000\u4e07');
  testCurrency('ja', 98765678, '¥9880\u4e07', '¥1\u5104');
  testCurrency('ja', 987656789, '¥9.88\u5104', '¥10\u5104');

  testCurrency('en_US', 1.2345, r'$1.23', r'$1');
  testCurrency('en_US', 1, r'$1.00', r'$1');
  testCurrency('en_US', 12, r'$12.00', r'$10');
  testCurrency('en_US', 12.3, r'$12.30', r'$10');
  testCurrency('en_US', 123, r'$123', r'$100');
  testCurrency('en_US', 1000, r'$1K', r'$1K');
  testCurrency('en_US', 1234, r'$1.23K', r'$1K');
  testCurrency('en_US', 12345, r'$12.3K', r'$10K');
  testCurrency('en_US', 123456, r'$123K', r'$100K');
  testCurrency('en_US', 1234567, r'$1.23M', r'$1M');

  // Check for order of currency symbol when currency is a suffix.
  testCurrency('ru', 4420, '4,42\u00A0тыс.\u00A0руб.', '4\u00A0тыс.\u00A0руб.');

  // Locales which don't have a suffix for thousands.
  testCurrency('it', 442, '442\u00A0€', '400\u00A0€');
  testCurrency('it', 4420, '4420\u00A0\$', '4000\u00A0\$', currency: 'CAD');
  testCurrency('it', 4420000, '4,42\u00A0Mio\u00A0\$', '4\u00A0Mio\u00A0\$',
      currency: 'USD');

  testCurrency('he', 335, '\u200F335 ₪', '\u200F300 ₪',
      reason: 'TODO(b/36488375): Short format throws away significant digits '
          'without good reason.');

  test('Explicit non-default symbol with compactCurrency', () {
    var format = NumberFormat.compactCurrency(locale: 'ja', symbol: '()');
    var result = format.format(98765);
    expect(result, '()9.88\u4e07');
  });
}

/// Tests for [NumberFormat.compactSimpleCurrency] and
/// [Numberformat.compactCurrency]. For `compactCurrency`, it also passes the
/// `symbol` parameter after which the result is expected to be the same as for
/// `compactSimpleCurrency`. The `expectedShort` string is compared to the
/// output of the formatters with significantDigits set to `1`.
void testCurrency(
    String locale, num number, String expected, String expectedShort,
    {String currency, String reason}) {
  test('Compact simple currency for $locale, $number', () {
    var format =
        NumberFormat.compactSimpleCurrency(locale: locale, name: currency);
    var result = format.format(number);
    expect(result, expected, reason: '$reason');
    var shortFormat =
        NumberFormat.compactSimpleCurrency(locale: locale, name: currency);
    shortFormat.significantDigits = 1;
    var shortResult = shortFormat.format(number);
    expect(shortResult, expectedShort, reason: 'shortFormat: $reason');
  });
  test('Compact currency for $locale, $number', () {
    var symbols = {
      'ja': '¥',
      'en_US': r'$',
      'ru': 'руб.',
      'it': '€',
      'he': '₪',
      'CAD': r'$',
      'USD': r'$'
    };
    var symbol = symbols[currency] ?? symbols[locale];
    var format = NumberFormat.compactCurrency(
        locale: locale, name: currency, symbol: symbol);
    var result = format.format(number);
    expect(result, expected, reason: '$reason');
    var shortFormat = NumberFormat.compactCurrency(
        locale: locale, name: currency, symbol: symbol);
    shortFormat.significantDigits = 1;
    var shortResult = shortFormat.format(number);
    expect(shortResult, expectedShort, reason: 'shortFormat: $reason');
  });
}

// TODO(alanknight): Don't just skip the whole locale if there's one problem
// case.
// TODO(alanknight): Fix the problems, or at least figure out precisely where
// the differences are.
var problemLocalesShort = [
  'am', // AM Suffixes differ, not sure why.
  'ca', // For CA, CLDR rules are different. Jumps from 0000 to 00 prefix, so
  // 11 digits prints as 11900.
  'es_419', // Some odd formatting rules for these which seem to be different
  // from CLDR. wants e.g. '160000000000k' Actual: '160 B'
  'es_ES', // The reverse of es_419 for a few cases. We're printing a longer
  // form.
  'es_US', // Like es_419 but not as many of them. e.g. Expected: '87700k'
  // Actual: '87.7 M'
  'es_MX', // like es_419
  'es',
  'fa',
  'fr_CA', // Several where PyICU isn't compacting. Expected: '988000000'
  // Actual: '988 M'.
  'gsw', // Suffixes disagree
  'in', // IN not compacting 54321, looks similar to tr.
  'id', // ID not compacting 54321, looks similar to tr.
  'ka', // K Slight difference in the suffix
  'kk', 'mn', // We're picking the wrong pattern for 654321.
  'lo', 'mk', 'my',
  'pt_PT', // Seems to differ in appending mil or not after thousands. pt_BR
  // does it.
  'sd', // ICU considers this locale data questionable
  'th', // TH Expected abbreviations as '1.09 พ.ล.' rather than '1.09 พ'
  'tr', // TR Doesn't have a 0B format, goes directly to 00B, as a result 54321
  // just prints as 54321
  'ur', // UR Fails one with Expected: '15 ٹریلین'  Actual: '150 کھرب'
];

/// Locales that have problems in the long format.
///
/// These are mostly minor differences in the characters, and many I can't read,
/// but I'm suspicious many of them are essentially the difference between
/// million and millions, which we don't distinguish. That's definitely the case
/// with e.g. DE, but our data definitely has Millionen throughout.
///
//TODO(alanknight): Narrow these down to particular numbers. Often it's just
// 999999.
var problemLocalesLong = [
  'ar', 'ar_DZ', 'ar_EG',
  'be', 'bg', 'bs',
  'ca', 'cs', 'da', 'de', 'de_AT', 'de_CH', 'el', 'es', 'es_419', 'es_ES',
  'es_MX', 'es_US', 'et', 'fi',
  'fil', // FIL is different, seems like a genuine difference in suffixes
  'fr', 'fr_CA',
  'fr_CH', // TODO(alanknight): million/millions, supported since CLDR 31.
  'ga', 'gl',
  'gsw', // GSW seems like we have long forms and pyICU doesn't
  'hr', 'is', 'it',
  'it_CH', 'lo', // LO seems to be picking up a different pattern.
  'lt', 'lv', 'mk',
  'my', // Seems to come out in the reverse order
  'nb', 'ne', 'no', 'no_NO', 'pl',
  'pt', // PT has some issues with scale as well, but I think it's differences
  // in the patterns.
  'pt_BR', 'pt_PT', 'ro', 'ru',
  'sd', // ICU considers this locale data questionable
  'sk', 'sl', 'sr', 'sr_Latn', 'sv', 'te', 'tl',
  'ur',
  'uk',
];

void validate(String locale, List<List<String>> expected) {
  validateShort(locale, expected);
  validateLong(locale, expected);
}

/// Check each bit of test data against the short compact format, both
/// formatting and parsing.
void validateShort(String locale, List<List<String>> expected) {
  if (problemLocalesShort.contains(locale)) {
    print("Skipping problem locale '$locale' for SHORT compact number tests");
    return;
  }
  var shortFormat = NumberFormat.compact(locale: locale);
  test('Validate $locale SHORT', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      validateNumber(number, shortFormat, data[1]);
      var int64Number = Int64(number);
      validateNumber(int64Number, shortFormat, data[1]);
      // TODO(alanknight): Make this work for MicroMoney
    }
  });
}

void validateLong(String locale, List<List<String>> expected) {
  if (problemLocalesLong.contains(locale)) {
    print("Skipping problem locale '$locale' for LONG compact number tests");
    return;
  }
  var longFormat = NumberFormat.compactLong(locale: locale);
  test('Validate $locale LONG', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      validateNumber(number, longFormat, data[2]);
    }
  });
}

void validateNumber(number, NumberFormat format, String expected) {
  var formatted = format.format(number);
  var ok = closeEnough(formatted, expected);
  if (!ok) {
    expect(
        '$formatted ${formatted.codeUnits}', '$expected ${expected.codeUnits}');
  }
  var parsed = format.parse(formatted);
  var rounded = roundForPrinting(number, format);
  expect((parsed - rounded) / rounded < 0.001, isTrue);
}

/// Duplicate a bit of the logic in formatting, where if we have a
/// number that will round to print differently depending on the number
/// of significant digits, we need to check that as well, e.g.
/// 999999 may print as 1M.
num roundForPrinting(number, NumberFormat format) {
  var originalLength = NumberFormat.numberOfIntegerDigits(number);
  var additionalDigits = originalLength - format.significantDigits;
  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;
    return rounded;
  }
  return number.toDouble();
}

final _nbsp = 0xa0;
final _nbspString = String.fromCharCode(_nbsp);

/// Return true if the strings are close enough to what we
/// expected to consider a pass.
///
/// In particular, there seem to be minor differences between what PyICU is
/// currently producing and the CLDR data. So if the strings differ only in the
/// presence or absence of a period at the end or of a space between the number
/// and the suffix, consider it close enough and return true.
bool closeEnough(String result, String reference) {
  var expected = reference.replaceAll(' ', _nbspString);
  if (result == expected) {
    return true;
  }
  if ('$result.' == expected) {
    return true;
  }
  if (result == '$expected.') {
    return true;
  }
  if (_oneSpaceOnlyDifference(result, expected)) {
    return true;
  }
  return false;
}

/// Do the two strings differ only by a single space being
/// omitted in one of them.
///
/// We assume non-breaking spaces because we
/// know that's what the Intl data uses. We already know the strings aren't
/// equal because that's checked first in the only caller.
bool _oneSpaceOnlyDifference(String result, String expected) {
  var resultWithoutSpaces =
      String.fromCharCodes(result.codeUnits.where((x) => x != _nbsp));
  var expectedWithoutSpaces =
      String.fromCharCodes(expected.codeUnits.where((x) => x != _nbsp));
  var resultDifference = result.length - resultWithoutSpaces.length;
  var expectedDifference = expected.length - expectedWithoutSpaces.length;
  return resultWithoutSpaces == expectedWithoutSpaces &&
      resultDifference <= 1 &&
      expectedDifference <= 1;
}

void validateFancy(more_testdata.CompactRoundingTestCase t) {
  var shortFormat = NumberFormat.compact(locale: 'en');
  if (t.maximumIntegerDigits != null) {
    shortFormat.maximumIntegerDigits = t.maximumIntegerDigits;
  }

  if (t.minimumIntegerDigits != null) {
    shortFormat.minimumIntegerDigits = t.minimumIntegerDigits;
  }

  if (t.maximumFractionDigits != null) {
    shortFormat.maximumFractionDigits = t.maximumFractionDigits;
  }

  if (t.minimumFractionDigits != null) {
    shortFormat.minimumFractionDigits = t.minimumFractionDigits;
  }

  if (t.minimumExponentDigits != null) {
    shortFormat.minimumExponentDigits = t.minimumExponentDigits;
  }

  if (t.significantDigits != null) {
    shortFormat.significantDigits = t.significantDigits;
  }

  test(t.toString(), () {
    expect(shortFormat.format(t.number), t.expected);
  });
}
