/// Tests for ICU compact format numbers (e.g. 1.2M instead of 1200000).
///
/// These tests check that the test cases match what ICU produces. They are not
/// testing the package:intl implementation, they only help verify consistent
/// behaviour across platforms.
@TestOn("!browser")
@Tags(['ffi'])
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:test/test.dart';

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

main() {
  var problemLocales = [
    // ICU produces numerals in Arabic script, package:intl uses Latin script.
    'ar',
    // package:intl includes some tweaks to compact numbers for Bengali.
    'bn',
  ];

  runICUTests(systemIcuVersion: 63, skipLocales: problemLocales);
}

void runICUTests(
    {int systemIcuVersion = null,
    String specialIcuLib = null,
    List<String> skipLocales = null}) {
  if (!setupICU(
      systemIcuVersion: systemIcuVersion, specialIcuLibPath: specialIcuLib)) {
    return;
  }

  print("Skipping problem locales $skipLocales.");
  testdata35.compactNumberTestData
      .removeWhere((k, v) => skipLocales.contains(k));
  testdata35.compactNumberTestData.forEach(validate);
  more_testdata.cldr35CompactNumTests.forEach(validateFancy);

  test('UNumberFormatter simple integer formatting', () {
    expect(FormatWithUnumf('en', 'precision-integer', 5142.3), '5,142');
  });
}

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

void validateShort(String locale, List<List<String>> expected) {
  test('Validate $locale SHORT', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      expect(FormatWithUnumf(locale, 'compact-short', number), data[1]);
    }
  });
}

void validateLong(String locale, List<List<String>> expected) {
  test('Validate $locale LONG', () {
    for (var data in expected) {
      var number = num.parse(data.first);
      expect(FormatWithUnumf(locale, 'compact-long', number), data[2]);
    }
  });
}

void validateFancy(more_testdata.CompactRoundingTestCase t) {
  var locale = 'en';
  var skel = 'compact-short';
  if (t.minimumIntegerDigits != null) {
    skel += ' integer-width/+' + '0' * t.minimumIntegerDigits;
  }
  if (t.significantDigits != null) {
    skel += ' ' + '@' * t.significantDigits;
  }
  if (t.minimumFractionDigits != null) {
    skel += ' .' + '0' * t.minimumFractionDigits;
    var maxFD = t.maximumFractionDigits ?? 3;
    skel += '#' * (maxFD - t.minimumFractionDigits);
  } else if (t.maximumFractionDigits != null) {
    skel += ' .' + '#' * t.maximumFractionDigits;
  }
  test(t.toString(), () {
    expect(FormatWithUnumf(locale, skel, t.number), t.expected,
        reason: 'Skeleton: $skel');
  });
}

UErrorNameOp u_errorName;
UnumfOpenForSkeletonAndLocaleOp unumf_openForSkeletonAndLocale;
UnumfOpenResultOp unumf_openResult;
UnumfFormatDoubleOp unumf_formatDouble;
UnumfFormatIntOp unumf_formatInt;
UnumfResultToStringOp unumf_resultToString;
UnumfCloseOp unumf_close;
UnumfCloseResultOp unumf_closeResult;

/// Sets up dart:ffi functions.
///
/// If [systemIcuVersion] is specified, and set to 63 for example, we load the
/// functions from libicuuc.so.63 and libicui18n.so.63 if available. If
/// libraries are lacking, function returns [false].
///
/// If [systemIcuVersion] is unspecified, we expect to find all functions in a
/// library with filename [specialIcuLibPath].
bool setupICU({int systemIcuVersion = null, String specialIcuLibPath = null}) {
  DynamicLibrary libicui18n;
  String icuVersionSuffix;
  if (systemIcuVersion != null) {
    icuVersionSuffix = '_$systemIcuVersion';
    try {
      DynamicLibrary libicuuc =
          DynamicLibrary.open('libicuuc.so.$systemIcuVersion');
      u_errorName = libicuuc.lookupFunction<NativeUErrorNameOp, UErrorNameOp>(
          "u_errorName$icuVersionSuffix");
      libicui18n = DynamicLibrary.open('libicui18n.so.$systemIcuVersion');
    } on ArgumentError catch (e) {
      print('Unable to test against ICU version $systemIcuVersion: $e');
      return false;
    }
  } else {
    icuVersionSuffix = '';
    libicui18n = DynamicLibrary.open(specialIcuLibPath);
    u_errorName = libicui18n.lookupFunction<NativeUErrorNameOp, UErrorNameOp>(
        "u_errorName$icuVersionSuffix");
  }

  unumf_openForSkeletonAndLocale = libicui18n.lookupFunction<
          NativeUnumfOpenForSkeletonAndLocaleOp,
          UnumfOpenForSkeletonAndLocaleOp>(
      "unumf_openForSkeletonAndLocale$icuVersionSuffix");
  unumf_openResult =
      libicui18n.lookupFunction<NativeUnumfOpenResultOp, UnumfOpenResultOp>(
          "unumf_openResult$icuVersionSuffix");
  unumf_formatDouble =
      libicui18n.lookupFunction<NativeUnumfFormatDoubleOp, UnumfFormatDoubleOp>(
          "unumf_formatDouble$icuVersionSuffix");
  unumf_formatInt =
      libicui18n.lookupFunction<NativeUnumfFormatIntOp, UnumfFormatIntOp>(
          "unumf_formatInt$icuVersionSuffix");
  unumf_resultToString = libicui18n.lookupFunction<NativeUnumfResultToStringOp,
      UnumfResultToStringOp>("unumf_resultToString$icuVersionSuffix");
  unumf_close = libicui18n.lookupFunction<NativeUnumfCloseOp, UnumfCloseOp>(
      "unumf_close$icuVersionSuffix");
  unumf_closeResult =
      libicui18n.lookupFunction<NativeUnumfCloseResultOp, UnumfCloseResultOp>(
          "unumf_closeResult$icuVersionSuffix");

  return true;
}

String FormatWithUnumf(String locale, String skeleton, num number) {
  // // Setup:
  // UErrorCode ec = U_ZERO_ERROR;
  // UNumberFormatter* uformatter =
  //     unumf_openForSkeletonAndLocale(u"precision-integer", -1, "en", &ec);
  // UFormattedNumber* uresult = unumf_openResult(&ec);
  // if (U_FAILURE(ec)) { return; }
  final cLocale = Utf8.toUtf8(locale);
  final cSkeleton = Utf16.toUtf16(skeleton);
  final cErrorCode = allocate<Int32>(count: 1);
  cErrorCode.value = 0;
  final uformatter =
      unumf_openForSkeletonAndLocale(cSkeleton, -1, cLocale, cErrorCode);
  free(cSkeleton);
  free(cLocale);
  var errorCode = cErrorCode.value;
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).toString());
  final uresult = unumf_openResult(cErrorCode);
  errorCode = cErrorCode.value;
  // Try to improve this once dart:ffi has extension methods:
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).toString());

  // // Format a double:
  // unumf_formatDouble(uformatter, 5142.3, uresult, &ec);
  // if (U_FAILURE(ec)) { return; }
  if (number is double) {
    unumf_formatDouble(uformatter, number, uresult, cErrorCode);
  } else {
    unumf_formatInt(uformatter, number, uresult, cErrorCode);
  }
  errorCode = cErrorCode.value;
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).toString());

  // // Export the string to a malloc'd buffer:
  // int32_t len = unumf_resultToString(uresult, NULL, 0, &ec);
  // // at this point, ec == U_BUFFER_OVERFLOW_ERROR
  // ec = U_ZERO_ERROR;
  // UChar* buffer = (UChar*) malloc((len+1)*sizeof(UChar));
  // unumf_resultToString(uresult, buffer, len+1, &ec);
  // if (U_FAILURE(ec)) { return; }
  // // buffer should equal "5,142"
  final reqLen = unumf_resultToString(uresult, nullptr.cast(), 0, cErrorCode);
  errorCode = cErrorCode.value;
  expect(errorCode, equals(15), // U_BUFFER_OVERFLOW_ERROR
      reason: u_errorName(errorCode).toString());
  cErrorCode.value = 0;
  final buffer = allocate<Utf16>(count: reqLen + 1);
  unumf_resultToString(uresult, buffer, reqLen + 1, cErrorCode);
  errorCode = cErrorCode.value;
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).toString());
  final result = buffer.toString();

  // // Cleanup:
  // unumf_close(uformatter);
  // unumf_closeResult(uresult);
  // free(buffer);
  unumf_close(uformatter);
  unumf_closeResult(uresult);
  free(buffer);
  free(cErrorCode);

  return result;
}

/// C signature for
/// [u_errorName()](http://icu-project.org/apiref/icu4c/utypes_8h.html#a89eb455526bb29bf5350ee861d81df92)
typedef NativeUErrorNameOp = Pointer<Utf8> Function(Int32 code);

/// Dart signature for
/// [u_errorName()](http://icu-project.org/apiref/icu4c/utypes_8h.html#a89eb455526bb29bf5350ee861d81df92)
typedef UErrorNameOp = Pointer<Utf8> Function(int code);

/// [UNumberFormatter](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a7c1238b2dd08f32f1ea245ece41e71bd)
class UNumberFormatter extends Struct {}

/// [UFormattedNumber](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a9d4030bdc4dd1ec4de828bf1bcf4b1b6)
class UFormattedNumber extends Struct {}

/// C signature for
/// [unumf_openForSkeletonAndLocale()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a29339e144833880bda36fb7c17032698)
typedef NativeUnumfOpenForSkeletonAndLocaleOp
    = Pointer<UNumberFormatter> Function(Pointer<Utf16> skeleton,
        Int32 skeletonLen, Pointer<Utf8> locale, Pointer<Int32> ec);

/// Dart signature for
/// [unumf_openForSkeletonAndLocale()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a29339e144833880bda36fb7c17032698)
typedef UnumfOpenForSkeletonAndLocaleOp = Pointer<UNumberFormatter> Function(
    Pointer<Utf16> skeleton,
    int skeletonLen,
    Pointer<Utf8> locale,
    Pointer<Int32> ec);

/// C signature for
/// [unumf_openResult()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a5bd2d297cb2664b4964d25fd41671dad)
typedef NativeUnumfOpenResultOp = Pointer<UFormattedNumber> Function(
    Pointer<Int32> ec);

/// Dart signature for
/// [unumf_openResult()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a5bd2d297cb2664b4964d25fd41671dad)
typedef UnumfOpenResultOp = Pointer<UFormattedNumber> Function(
    Pointer<Int32> ec);

/// C signature for
/// [unumf_formatDouble()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#af5f79e43adc900f07b3ba90b6315944e)
typedef NativeUnumfFormatDoubleOp = Void Function(
    Pointer<UNumberFormatter> uformatter,
    Double value,
    Pointer<UFormattedNumber> uresult,
    Pointer<Int32> ec);

/// Dart signature for
/// [unumf_formatDouble()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#af5f79e43adc900f07b3ba90b6315944e)
typedef UnumfFormatDoubleOp = void Function(
    Pointer<UNumberFormatter> uformatter,
    double value,
    Pointer<UFormattedNumber> uresult,
    Pointer<Int32> ec);

/// C signature for
/// [unumf_formatInt()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a459b9313ed05fc98c9cd125eb9c1a625)
typedef NativeUnumfFormatIntOp = Void Function(
    Pointer<UNumberFormatter> uformatter,
    Int32 value,
    Pointer<UFormattedNumber> uresult,
    Pointer<Int32> ec);

/// Dart signature for
/// [unumf_formatInt()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a459b9313ed05fc98c9cd125eb9c1a625)
typedef UnumfFormatIntOp = void Function(Pointer<UNumberFormatter> uformatter,
    int value, Pointer<UFormattedNumber> uresult, Pointer<Int32> ec);

/// C signature for
/// [unumf_resultToString()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a72131183633fda6851c35e37ffd821a1)
typedef NativeUnumfResultToStringOp = Int32 Function(
    Pointer<UFormattedNumber> uresult,
    Pointer<Utf16> buffer,
    Int32 bufferCapacity,
    Pointer<Int32> ec);

/// Dart signature for
/// [unumf_resultToString()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a72131183633fda6851c35e37ffd821a1)
typedef UnumfResultToStringOp = int Function(Pointer<UFormattedNumber> uresult,
    Pointer<Utf16> buffer, int bufferCapacity, Pointer<Int32> ec);

/// C signature for
/// [unumf_close()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a6f47836ca05077fc912ad24e462312c6)
typedef NativeUnumfCloseOp = Void Function(
    Pointer<UNumberFormatter> uformatter);

/// Dart signature for
/// [unumf_close()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a6f47836ca05077fc912ad24e462312c6)
typedef UnumfCloseOp = void Function(Pointer<UNumberFormatter> uformatter);

/// C signature for
/// [unumf_closeResult()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a78f19cef14a2db1a0eb62a8b724eb123)
typedef NativeUnumfCloseResultOp = Void Function(
    Pointer<UFormattedNumber> uresult);

/// Dart signature for
/// [unumf_closeResult()](http://icu-project.org/apiref/icu4c/unumberformatter_8h.html#a78f19cef14a2db1a0eb62a8b724eb123)
typedef UnumfCloseResultOp = void Function(Pointer<UFormattedNumber> uresult);
