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

/// Tests for compact format numbers, e.g. 1.2M rather than 1,200,000
import 'dart:math';

import 'package:fixnum/fixnum.dart';
import 'package:intl/intl.dart';
import 'package:intl/number_symbols_data.dart' as patterns;
import 'package:test/test.dart';

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 as int);
      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);
  });
}
