/// 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")
import 'dart:convert';
import 'dart:ffi' as ffi;
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}) {
  ffi.DynamicLibrary libicui18n;
  String icuVersionSuffix;
  if (systemIcuVersion != null) {
    icuVersionSuffix = '_$systemIcuVersion';
    try {
      ffi.DynamicLibrary libicuuc =
          ffi.DynamicLibrary.open('libicuuc.so.$systemIcuVersion');
      u_errorName = libicuuc.lookupFunction<NativeUErrorNameOp, UErrorNameOp>(
          "u_errorName$icuVersionSuffix");
      libicui18n = ffi.DynamicLibrary.open('libicui18n.so.$systemIcuVersion');
    } on ArgumentError catch (e) {
      print('Unable to test against ICU version $systemIcuVersion: $e');
      return false;
    }
  } else {
    icuVersionSuffix = '';
    libicui18n = ffi.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.allocate(locale);
  final cSkeleton = Utf16.allocate(skeleton);
  final cErrorCode = ffi.Pointer<ffi.Int32>.allocate(count: 1);
  cErrorCode.store(0);
  final uformatter =
      unumf_openForSkeletonAndLocale(cSkeleton, -1, cLocale, cErrorCode);
  cSkeleton.free();
  cLocale.free();
  var errorCode = cErrorCode.load<int>();
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).load<Utf8>().toString());
  final uresult = unumf_openResult(cErrorCode);
  errorCode = cErrorCode.load();
  // Try to improve this once dart:ffi has extension methods:
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).load<Utf8>().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.load();
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).load<Utf8>().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, ffi.nullptr.cast(), 0, cErrorCode);
  errorCode = cErrorCode.load();
  expect(errorCode, equals(15), // U_BUFFER_OVERFLOW_ERROR
      reason: u_errorName(errorCode).load<Utf8>().toString());
  cErrorCode.store(0);
  final buffer = ffi.Pointer<Utf16>.allocate(count: reqLen + 1);
  unumf_resultToString(uresult, buffer, reqLen + 1, cErrorCode);
  errorCode = cErrorCode.load();
  expect(errorCode, lessThanOrEqualTo(0),
      reason: u_errorName(errorCode).load<Utf8>().toString());
  final bufferContent = buffer.load<Utf16>();
  final result = bufferContent.toString();

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

  return result;
}

/// Represents a char* UTF-8 string in C memory.
class Utf8 extends ffi.Struct<Utf8> {
  @ffi.Uint8()
  int char;

  /// Allocate a [CString] and populates it with [dartStr].
  ///
  /// This [CString] is not managed by an [Arena]. Please ensure to [free] the
  /// memory manually!
  static ffi.Pointer<Utf8> allocate(String dartStr) {
    List<int> units = Utf8Encoder().convert(dartStr);
    ffi.Pointer<Utf8> str = ffi.Pointer<Utf8>.allocate(count: units.length + 1);
    for (int i = 0; i < units.length; ++i) {
      str.elementAt(i).load<Utf8>().char = units[i];
    }
    str.elementAt(units.length).load<Utf8>().char = 0;
    return str;
  }

  /// Read the string for C memory into Dart.
  String toString() {
    final str = addressOf;
    if (str == ffi.nullptr) return null;
    int len = 0;
    while (str.elementAt(++len).load<Utf8>().char != 0);
    List<int> units = List(len);
    for (int i = 0; i < len; ++i) {
      units[i] = str.elementAt(i).load<Utf8>().char;
    }
    return Utf8Decoder().convert(units);
  }
}

/// Represents a UChar* in C memory.
class Utf16 extends ffi.Struct<Utf16> {
  @ffi.Uint16()
  int char;

  /// Allocates a Pointer<Utf16> and populates it with [dartStr].
  ///
  /// Please ensure to [free] the memory manually!
  static ffi.Pointer<Utf16> allocate(String dartStr) {
    List<int> units = dartStr.codeUnits;
    ffi.Pointer<Utf16> str =
        ffi.Pointer<Utf16>.allocate(count: (units.length + 1));
    for (int i = 0; i < units.length; ++i) {
      str.elementAt(i).load<Utf16>().char = units[i];
    }
    str.elementAt(units.length).load<Utf16>().char = 0;
    return str;
  }

  /// Read the string for C memory into Dart.
  String toString() {
    final str = addressOf;
    if (str == ffi.nullptr) return null;
    int len = 0;
    while (str.elementAt(++len).load<Utf16>().char != 0);
    List<int> units = List(len);
    for (int i = 0; i < len; ++i) {
      units[i] = str.elementAt(i).load<Utf16>().char;
    }
    return String.fromCharCodes(units);
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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