/// Tests for compact number formatting in pure Dart and in ECMAScript.
///
/// TODO(b/36488375): run all these tests against both implementations to prove
/// consistency when the bug is fixed. Also fix documentation and perhaps
/// merge tests: these tests currently also touch non-compact currency
/// formatting.

/// We use @Tags rather than @TestOn to be able to specify something that can be
/// ignored when using a build system that can't read dart_test.yaml. This
/// depends on https://github.com/tc39/proposal-unified-intl-numberformat.
@Tags(['unifiedNumberFormat'])

import 'package:intl/intl.dart' as intl;
import 'package:js/js_util.dart' as js;
import 'package:test/test.dart';

import 'compact_number_test_data.dart' as testdata35;
import 'more_compact_number_test_data.dart' as more_testdata;

void main() {
  testdata35.compactNumberTestData.forEach(validate);
  more_testdata.cldr35CompactNumTests.forEach(validateMore);

  test('RTL currency formatting', () {
    var basic = intl.NumberFormat.currency(locale: 'he');
    expect(basic.format(1234), '\u200F1,234.00 ILS');
    basic = intl.NumberFormat.currency(locale: 'he', symbol: '₪');
    expect(basic.format(1234), '\u200F1,234.00 ₪');
    expect(ecmaFormatNumber('he', 1234, style: 'currency', currency: 'ILS'),
        '\u200F1,234.00 ₪');

    var compact = intl.NumberFormat.compactCurrency(locale: 'he');
    // Awkward:
    expect(compact.format(1234), 'ILS \u200F1.23K');
    compact = intl.NumberFormat.compactCurrency(locale: 'he', symbol: '₪');
    // Awkward:
    expect(compact.format(1234), '₪ \u200F1.23K');
    // ECMAScript skips the RTL character for notation:'compact':
    expect(
        ecmaFormatNumber('he', 1234,
            style: 'currency', currency: 'ILS', notation: 'compact'),
        '₪ 1.2K');
    // short/long compactDisplay doesn't change anything here:
    expect(
        ecmaFormatNumber('he', 1234,
            style: 'currency',
            currency: 'ILS',
            notation: 'compact',
            compactDisplay: 'short'),
        '₪ 1.2K');
    expect(
        ecmaFormatNumber('he', 1234,
            style: 'currency',
            currency: 'ILS',
            notation: 'compact',
            compactDisplay: 'long'),
        '₪ 1.2K');

    var compactSimple = intl.NumberFormat.compactSimpleCurrency(locale: 'he');
    expect(compactSimple.format(1234), '₪ \u200F1.23K');
  });
}

String ecmaFormatNumber(String locale, num number,
    {String style, String currency, String notation, String compactDisplay}) {
  var options = js.newObject();
  if (notation != null) js.setProperty(options, 'notation', notation);
  if (compactDisplay != null) {
    js.setProperty(options, 'compactDisplay', compactDisplay);
  }
  if (style != null) js.setProperty(options, 'style', style);
  if (currency != null) js.setProperty(options, 'currency', currency);
  return js.callMethod(number, 'toLocaleString', [locale, options]);
}

var ecmaProblemLocalesShort = [
  // Not supported in Chrome:
  'af', 'az', 'be', 'br', 'bs', 'eu', 'ga', 'gl', 'gsw', 'haw', 'hy', 'is',
  'ka', 'kk', 'km', 'ky', 'ln', 'lo', 'mk', 'mn', 'mt', 'my', 'ne', 'no',
  'no-NO', 'or', 'pa', 'si', 'sq', 'ur', 'uz', 'ps',
];

var ecmaProblemLocalesLong = ecmaProblemLocalesShort +
    [
      // Short happens to match 'en', but actually not in Chrome:
      'chr', 'cy', 'tl', 'zu'
    ];

String fixLocale(String locale) {
  return locale.replaceAll('_', '-');
}

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

void validateShort(String locale, List<List<String>> expected) {
  if (ecmaProblemLocalesShort.contains(locale)) {
    print("Skipping problem locale '$locale' for SHORT compact number tests");
    return;
  }

  test('Validate $locale SHORT', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      expect(ecmaFormatNumber(locale, number, notation: 'compact'), data[1]);
    }
  });
}

void validateLong(String locale, List<List<String>> expected) {
  if (ecmaProblemLocalesLong.contains(locale)) {
    print("Skipping problem locale '$locale' for LONG compact number tests");
    return;
  }

  test('Validate $locale LONG', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      expect(
          ecmaFormatNumber(locale, number,
              notation: 'compact', compactDisplay: 'long'),
          data[2]);
    }
  });
}

void validateMore(more_testdata.CompactRoundingTestCase t) {
  var options = js.newObject();
  js.setProperty(options, 'notation', 'compact');
  if (t.maximumIntegerDigits != null) {
    js.setProperty(options, 'maximumIntegerDigits', t.maximumIntegerDigits);
  }

  if (t.minimumIntegerDigits != null) {
    js.setProperty(options, 'minimumIntegerDigits', t.minimumIntegerDigits);
  }

  if (t.maximumFractionDigits != null) {
    js.setProperty(options, 'maximumFractionDigits', t.maximumFractionDigits);
  }

  if (t.minimumFractionDigits != null) {
    js.setProperty(options, 'minimumFractionDigits', t.minimumFractionDigits);
  }

  if (t.minimumExponentDigits != null) {
    js.setProperty(options, 'minimumExponentDigits', t.minimumExponentDigits);
  }

  if (t.significantDigits != null) {
    js.setProperty(options, 'minimumSignificantDigits', t.significantDigits);
    js.setProperty(options, 'maximumSignificantDigits', t.significantDigits);
  }

  test(t.toString(), () {
    expect(js.callMethod(t.number, 'toLocaleString', ['en-US', options]),
        t.expected);
  });
}
