// Copyright (c) 2019, 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.

// `MessageFormat` is a "locale aware printf", with plural / gender support.
///
/// `MessageFormat` prepares strings for display to users, with optional
/// arguments (variables/placeholders). The arguments can occur in any order,
/// which is necessary for translation into languages with different grammars.
/// It supports syntax to represent plurals and select options.
library message_format;

import 'dart:collection';
import 'intl.dart';

/// **MessageFormat grammar:**
/// ```
/// message := messageText (argument messageText)*
/// argument := simpleArg | pluralArg | selectArg
///
/// simpleArg := "#" | "{" argNameOrNumber "}"
/// pluralArg := "{" argNameOrNumber "," "plural" "," pluralStyle "}"
/// selectArg := "{" argNameOrNumber "," "select" "," selectStyle "}"
///
/// argNameOrNumber := identifier | number
///
/// pluralStyle := [offsetValue] (pluralSelector "{" message "}")+
/// offsetValue := "offset:" number
/// pluralSelector := explicitValue | pluralKeyword
/// explicitValue := "=" number  // adjacent, no white space in between
/// pluralKeyword := "zero" | "one" | "two" | "few" | "many" | "other"
///
/// selectStyle := (selectSelector "{" message "}")+
/// selectSelector := keyword
///
/// identifier := [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
/// number := "0" | ("1".."9" ("0".."9")*)
/// ```
///
/// **NOTE:** "#" has special meaning only inside a plural block.
/// It is "connected" to the argument of the plural, but the value of #
/// is the value of the plural argument minus the offset.
///
/// **Quoting/Escaping:** if syntax characters occur in the text portions,
/// then they need to be quoted by enclosing the syntax in pairs of ASCII
/// apostrophes.
///
/// A pair of ASCII apostrophes always represents one ASCII apostrophe,
/// similar to %% in printf representing one %, although this rule still
/// applies inside quoted text.
///
/// ("This '{isn''t}' obvious" → "This {isn't} obvious")
///
/// An ASCII apostrophe only starts quoted text if it immediately precedes
/// a character that requires quoting (that is, "only where needed"), and
/// works the same in nested messages as on the top level of the pattern.
///
/// **Recommendation:** Use the real apostrophe (single quote) character ’
/// (U+2019) for human-readable text, and use the ASCII apostrophe ' (U+0027)
/// only in program syntax, like escaping.
///
/// This is a subset of the ICU MessageFormat syntax:
///   http://userguide.icu-project.org/formatparse/messages.
///
/// **Message example:**
/// ```
/// I see {NUM_PEOPLE, plural, offset:1
///         =0 {no one at all}
///         =1 {{WHO}}
///         one {{WHO} and one other person}
///         other {{WHO} and # other people}}
/// in {PLACE}.
/// ```
///
/// Calling `format({'NUM_PEOPLE': 2, 'WHO': 'Mark', 'PLACE': 'Athens'})` would
/// produce `"I see Mark and one other person in Athens."` as output.
///
/// Calling `format({'NUM_PEOPLE': 5, 'WHO': 'Mark', 'PLACE': 'Athens'})` would
/// produce `"I see Mark and 4 other people in Athens."` as output.
/// Notice how the "#" is the value of `NUM_PEOPLE` - 1 (the offset).
///
/// Another important thing to notice is the existence of both `"=1"` and
/// `"one"`. You should think of the plural keywords as names for "buckets of
/// numbers" which have only a loose connection to the numerical value.
///
/// In English there is no difference, but for example in Russian all the
/// numbers that end with `"1"` but not with `"11"` are mapped to `"one"`
///
/// For more information please visit:
/// http://cldr.unicode.org/index/cldr-spec/plural-rules and
/// http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html

// The implementation is based on the
// [Closure goog.i18n.MessageFormat](https://google.github.io/closure-library/api/goog.i18n.MessageFormat.html)
// sources at https://github.com/google/closure-library/blob/master/closure/goog/i18n/messageformat.js,
// so we should try to keep potential fixes in sync.
//
// The initial parsing done by [_extractParts] breaks the pattern into top
// level strings and {...} blocks [_ElementTypeAndVal]
//
// The values are all strings, but the ones that contain curly brackets
// are classified as `blocks` and will be parsed again (recursively)
//
// The second round of parsing takes the parts from above and refines them
// into _BlockTypeAndVal. After this point we have different types of blocks
// (string, plural, ordinal, select, ...)

class MessageFormat {
  /// The locale to use for plural, ordinal, decisions,
  /// number / date / time formatting
  final String _locale;

  /// The pattern we parse and apply positional parameters to.
  String? _pattern;

  /// All encountered literals during parse stage.
  Queue<String>? _initialLiterals;

  /// Working list with all encountered literals during parse and format stages.
  Queue<String>? _literals;

  /// Input pattern gets parsed into objects for faster formatting.
  Queue<_BlockTypeAndVal>? _parsedPattern;

  /// Locale aware number formatter.
  final NumberFormat _numberFormat;

  /// Literal strings, including '', are replaced with \uFDDF_x_ for parsing.
  ///
  /// They are recovered during format phase.
  /// \uFDDF is a Unicode nonprinting character, not expected to be found in the
  /// typical message.
  static const String _literalPlaceholder = '\uFDDF_';

  /// Mandatory option in both select and plural form.
  static const String _other = 'other';

  /// Regular expression for looking for string literals.
  static final RegExp _regexLiteral = RegExp("'([{}#].*?)'");

  /// Regular expression for looking for '' in the message.
  static final RegExp _regexDoubleApostrophe = RegExp("''");

  /// Create a MessageFormat for the ICU message string [pattern].
  /// It does parameter substitutions in a locale-aware way.
  /// The syntax is similar to the one used by ICU and is described in the
  /// grammar above.
  MessageFormat(String pattern, {String locale = 'en'})
      : _locale = locale,
        _pattern = pattern,
        _numberFormat = NumberFormat.decimalPattern(locale);

  /// Returns a formatted message, treating '#' as a special placeholder.
  ///
  /// It represents the number (plural_variable - offset).
  ///
  /// The [namedParameters] either influence the formatting or are used as
  /// actual data.
  /// I.e. in call to `fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'})`, the
  /// map `{'NUM_PEOPLE': 5, 'NAME': 'Angela'}` holds parameters.
  /// `NUM_PEOPLE` parameter could mean 5 people, which could influence plural
  /// format, and `NAME` parameter is just a data to be printed out in proper
  /// position.
  String format([Map<String, Object>? namedParameters]) {
    return _format(false, namedParameters);
  }

  /// Returns a formatted message, treating '#' as literal character.
  ///
  /// The [namedParameters] either influence the formatting or are used as
  /// actual data.
  /// I.e. in call to `fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'})`, the
  /// map `{'NUM_PEOPLE': 5, 'NAME': 'Angela'}` holds positional parameters.
  /// `NUM_PEOPLE` parameter could mean 5 people, which could influence plural
  /// format, and `NAME` parameter is just a data to be printed out in proper
  /// position.
  String formatIgnoringPound([Map<String, Object>? namedParameters]) {
    return _format(true, namedParameters);
  }

  /// Returns a formatted message.
  ///
  /// The [namedParameters] either influence the formatting or are used as
  /// actual data.
  /// I.e. in call to `fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'})`, the
  /// map `{'NUM_PEOPLE': 5, 'NAME': 'Angela'}` holds positional parameters.
  /// `NUM_PEOPLE` parameter could mean 5 people, which could influence plural
  /// format, and `NAME` parameter is just a data to be printed out in proper
  /// position.
  /// If [ignorePound] is true, treat '#' in plural messages as a
  /// literal character, else treat it as an ICU syntax character, resolving
  /// to the number (plural_variable - offset).
  String _format(bool ignorePound, [Map<String, Object>? namedParameters]) {
    _init();
    if (_parsedPattern == null || _parsedPattern!.isEmpty) {
      return '';
    }
    // Clone, we don't want to damage the original
    _literals = Queue<String>()..addAll(_initialLiterals!);

    // Implementation notes: this seems inefficient, we could in theory do the
    // replace + join in one go.
    // But would make the code even more unreadable than it is.
    //
    // `_formatBlock` replaces "full blocks"
    // For example replaces this:
    //   `... {count, plural, =1 {one file} few {...} many {...} other {# files} ...`
    // with
    //    `... one file ...`
    //
    // The replace after that (with `message.replaceFirst`) is only replacing
    // simple parameters (`...{expDate} ... {count}...`)
    //
    // So `_formatBlock` is ugly, potentially recursive.
    // `message.replaceFirst` is very simple, flat.
    //
    // I agree that there might be some performance loss.
    // But in real use the messages don't have that many arguments.
    // If we think printf, how many arguments are common?
    // Probably less than 5 or so.
    var messageParts = Queue<String>();
    _formatBlock(_parsedPattern!, namedParameters!, ignorePound, messageParts);
    var message = messageParts.join('');

    if (!ignorePound) {
      _checkAndThrow(!message.contains('#'), 'Not all # were replaced.');
    }

    while (_literals!.isNotEmpty) {
      message = message.replaceFirst(
          _buildPlaceholder(_literals!), _literals!.removeLast());
    }

    return message;
  }

  /// Takes the parsed tree and the parameters, appending to result.
  ///
  /// The [parsedBlocks] parameter holds parsed tree.
  /// [namedParameters] are parameters that either influence the formatting
  /// or are used as actual data.
  /// If [ignorePound] is true, treat '#' in plural messages as a
  /// literal character, else treat it as an ICU syntax character, resolving
  /// to the number (plural_variable - offset).
  /// Each formatting stage appends its product to the [result].
  /// It can be recursive, as plural / select contain full message patterns.
  void _formatBlock(
      Queue<_BlockTypeAndVal> parsedBlocks,
      Map<String, Object> namedParameters,
      bool ignorePound,
      Queue<String> result) {
    for (var currentPattern in parsedBlocks) {
      var patternValue = currentPattern._value;
      var patternType = currentPattern._type;

      switch (patternType) {
        case _BlockType.string:
          result.add(patternValue as String);
          break;
        case _BlockType.simple:
          _formatSimplePlaceholder(
              patternValue as String, namedParameters, result);
          break;
        case _BlockType.select:
          _checkAndThrow(patternValue is Map<String, Object>,
              'The value should be a map: $patternValue');
          var mapPattern = patternValue as Map<String, Object>;
          _formatSelectBlock(mapPattern, namedParameters, ignorePound, result);
          break;
        case _BlockType.plural:
          _formatPluralOrdinalBlock(patternValue as Map<String, Object>,
              namedParameters, _PluralRules.select, ignorePound, result);
          break;
        case _BlockType.ordinal:
          _formatPluralOrdinalBlock(patternValue as Map<String, Object>,
              namedParameters, _OrdinalRules.select, ignorePound, result);
          break;
        default:
          _checkAndThrow(false, 'Unrecognized block type: $patternType');
      }
    }
  }

  /// Formats a simple placeholder.
  ///
  /// [parsedBlocks] is an object containing placeholder info.
  /// The [namedParameters] that are used as actual data.
  /// Each formatting stage appends its product to the [result].
  void _formatSimplePlaceholder(String parsedBlocks,
      Map<String, Object> namedParameters, Queue<String> result) {
    var value = namedParameters[parsedBlocks];
    if (!_isDef(value)) {
      result.add('Undefined parameter - $parsedBlocks');
      return;
    }

    // Don't push the value yet, it may contain any of # { } in it which
    // will break formatter. Insert a placeholder and replace at the end.
    String strValue;
    if (value is int) {
      strValue = _numberFormat.format(value);
    } else if (value is String) {
      strValue = value;
    } else {
      strValue = value.toString();
    }
    _literals!.add(strValue);
    result.add(_buildPlaceholder(_literals!));
  }

  /// Formats select block. Only one option is selected.
  ///
  /// [parsedBlocks] is an object containing select block info.
  /// [namedParameters] are parameters that either influence the formatting
  /// or are used as actual data.
  /// If [ignorePound] is true, treat '#' in plural messages as a
  /// literal character, else treat it as an ICU syntax character, resolving
  /// to the number (plural_variable - offset).
  /// Each formatting stage appends its product to the [result].
  void _formatSelectBlock(
      Map<String, Object> parsedBlocks,
      Map<String, Object> namedParameters,
      bool ignorePound,
      Queue<String> result) {
    var argumentName = parsedBlocks['argumentName'];
    if (!_isDef(namedParameters[argumentName])) {
      result.add('Undefined parameter - $argumentName');
      return;
    }

    var option =
        parsedBlocks[namedParameters[argumentName]] as Queue<_BlockTypeAndVal>?;
    if (!_isDef(option)) {
      option = parsedBlocks[_other] as Queue<_BlockTypeAndVal>?;
      _checkAndThrow(option != null,
          'Invalid option or missing other option for select block.');
    }

    _formatBlock(option!, namedParameters, ignorePound, result);
  }

  /// Formats `plural` / `selectordinal` block, selects an option, replaces `#`
  ///
  /// [parsedBlocks] is an object containing plural block info.
  /// [namedParameters] are parameters that either influence the formatting
  /// or are used as actual data.
  /// The [pluralSelector] is a select function from pluralRules or ordinalRules
  /// which determines which plural/ordinal form to use based on the input
  /// number's cardinality.
  /// If [ignorePound] is true, treat '#' in plural messages as a
  /// literal character, else treat it as an ICU syntax character, resolving
  /// to the number (plural_variable - offset).
  /// Each formatting stage appends its product to the [result].
  void _formatPluralOrdinalBlock(
      Map<String, Object> parsedBlocks,
      dynamic namedParameters,
      Function(num, String) pluralSelector,
      bool ignorePound,
      Queue<String> result) {
    var argumentName = parsedBlocks['argumentName'];
    var argumentOffset = parsedBlocks['argumentOffset'];
    var pluralValue = namedParameters[argumentName];

    if (!_isDef(pluralValue)) {
      result.add('Undefined parameter - $argumentName');
      return;
    }

    var numPluralValue =
        pluralValue is num ? pluralValue : double.tryParse(pluralValue);
    if (numPluralValue == null) {
      result.add('Invalid parameter - $argumentName');
      return;
    }

    var numArgumentOffset = argumentOffset is num
        ? argumentOffset
        : double.tryParse(argumentOffset as String);
    if (numArgumentOffset == null) {
      result.add('Invalid offset - $argumentOffset');
      return;
    }

    var diff = numPluralValue - numArgumentOffset;

    // Check if there is an exact match.
    var option =
        parsedBlocks[namedParameters[argumentName]] as Queue<_BlockTypeAndVal>?;
    if (!_isDef(option)) {
      option = parsedBlocks[namedParameters[argumentName].toString()]
          as Queue<_BlockTypeAndVal>?;
    }
    if (!_isDef(option)) {
      var item = pluralSelector(diff.abs(), _locale);
      _checkAndThrow(item is String, 'Invalid plural key.');

      option = parsedBlocks[item] as Queue<_BlockTypeAndVal>?;

      // If option is not provided fall back to "other".
      if (!_isDef(option)) {
        option = parsedBlocks[_other] as Queue<_BlockTypeAndVal>?;
      }

      _checkAndThrow(option != null,
          'Invalid option or missing other option for plural block.');
    }

    var pluralResult = Queue<String>();
    _formatBlock(option!, namedParameters, ignorePound, pluralResult);
    var plural = pluralResult.join('');
    if (ignorePound) {
      result.add(plural);
    } else {
      var localeAwareDiff = _numberFormat.format(diff);
      result.add(plural.replaceAll('#', localeAwareDiff));
    }
  }

  /// Set up the MessageFormat.
  ///
  /// Parses input pattern into an array, for faster reformatting with
  /// different input parameters.
  /// Parsing is locale independent.
  void _init() {
    if (_pattern != null) {
      _initialLiterals = Queue<String>();
      var pattern = _insertPlaceholders(_pattern!);

      _parsedPattern = _parseBlock(pattern);
      _pattern = null;
    }
  }

  /// Replaces string literals with literal placeholders in [pattern].
  ///
  /// Literals are string of the form '}...', '{...' and '#...' where ... is
  /// set of characters not containing '
  /// Builds a dictionary so we can recover literals during format phase.
  String _insertPlaceholders(String pattern) {
    var literals = _initialLiterals!;
    var buildPlaceholder = _buildPlaceholder;

    // First replace '' with single quote placeholder since they can be found
    // inside other literals.
    pattern = pattern.replaceAllMapped(_regexDoubleApostrophe, (match) {
      literals.add("'");
      return buildPlaceholder(literals);
    });

    pattern = pattern.replaceAllMapped(_regexLiteral, (match) {
      // match, text
      var text = match.group(1)!;
      literals.add(text);
      return buildPlaceholder(literals);
    });

    return pattern;
  }

  /// Breaks [pattern] into strings and top level {...} blocks.
  Queue<_ElementTypeAndVal> _extractParts(String pattern) {
    var prevPos = 0;
    var braceStack = Queue<String>();
    var results = Queue<_ElementTypeAndVal>();

    var braces = RegExp('[{}]');

    Match match;
    for (match in braces.allMatches(pattern)) {
      var pos = match.start;
      if (match[0] == '}') {
        String? brace;
        try {
          brace = braceStack.removeLast();
        } on StateError {
          _checkAndThrow(brace != '}', 'No matching } for {.');
        }
        _checkAndThrow(brace == '{', 'No matching { for }.');

        if (braceStack.isEmpty) {
          // End of the block.
          var part = _ElementTypeAndVal(
              _ElementType.block, pattern.substring(prevPos, pos));
          results.add(part);
          prevPos = pos + 1;
        }
      } else {
        if (braceStack.isEmpty) {
          var substring = pattern.substring(prevPos, pos);
          if (substring != '') {
            results.add(_ElementTypeAndVal(_ElementType.string, substring));
          }
          prevPos = pos + 1;
        }
        braceStack.add('{');
      }
    }

    // Take care of the final string, and check if the braceStack is empty.
    _checkAndThrow(
        braceStack.isEmpty, 'There are mismatched { or } in the pattern.');

    var substring = pattern.substring(prevPos);
    if (substring != '') {
      results.add(_ElementTypeAndVal(_ElementType.string, substring));
    }

    return results;
  }

  /// A regular expression to parse the plural block.
  ///
  /// It extracts the argument index and offset (if any).
  static final RegExp _pluralBlockRe =
      RegExp('^\\s*(\\w+)\\s*,\\s*plural\\s*,(?:\\s*offset:(\\d+))?');

  /// A regular expression to parse the ordinal block.
  ///
  /// It extracts the argument index.
  static final RegExp _ordinalBlockRe =
      RegExp('^\\s*(\\w+)\\s*,\\s*selectordinal\\s*,');

  /// A regular expression to parse the select block.
  ///
  /// It extracts the argument index.
  static final RegExp _selectBlockRe =
      RegExp('^\\s*(\\w+)\\s*,\\s*select\\s*,');

  /// Detects the block type of the [pattern].
  _BlockType _parseBlockType(String pattern) {
    if (_pluralBlockRe.hasMatch(pattern)) {
      return _BlockType.plural;
    }

    if (_ordinalBlockRe.hasMatch(pattern)) {
      return _BlockType.ordinal;
    }

    if (_selectBlockRe.hasMatch(pattern)) {
      return _BlockType.select;
    }

    if (RegExp('^\\s*\\w+\\s*').hasMatch(pattern)) {
      return _BlockType.simple;
    }

    return _BlockType.unknown;
  }

  /// Parses generic block.
  ///
  /// Takes the [pattern], which is the content of the block to parse,
  /// and returns sub-blocks marked as strings, select, plural, ...
  Queue<_BlockTypeAndVal> _parseBlock(String pattern) {
    var result = Queue<_BlockTypeAndVal>();
    var parts = _extractParts(pattern);
    for (var thePart in parts) {
      _BlockTypeAndVal? block;
      if (_ElementType.string == thePart._type) {
        block = _BlockTypeAndVal(_BlockType.string, thePart._value);
      } else if (_ElementType.block == thePart._type) {
        var blockType = _parseBlockType(thePart._value);

        switch (blockType) {
          case _BlockType.select:
            block = _BlockTypeAndVal(
                _BlockType.select, _parseSelectBlock(thePart._value));
            break;
          case _BlockType.plural:
            block = _BlockTypeAndVal(
                _BlockType.plural, _parsePluralBlock(thePart._value));
            break;
          case _BlockType.ordinal:
            block = _BlockTypeAndVal(
                _BlockType.ordinal, _parseOrdinalBlock(thePart._value));
            break;
          case _BlockType.simple:
            block = _BlockTypeAndVal(_BlockType.simple, thePart._value);
            break;
          default:
            _checkAndThrow(
                false, 'Unknown block type for pattern: ${thePart._value}');
        }
      } else {
        _checkAndThrow(false, 'Unknown part of the pattern.');
      }
      result.add(block!);
    }

    return result;
  }

  /// Parses a select type of a block and produces an object for it.
  ///
  /// The [pattern] is the  sub-pattern that needs to be parsed as select,
  /// and returns an object with select block info.
  Map<String, Object> _parseSelectBlock(String pattern) {
    var argumentName = '';
    var replaceRegex = _selectBlockRe;
    pattern = pattern.replaceFirstMapped(replaceRegex, (match) {
      // string, name
      argumentName = match.group(1)!;
      return '';
    });
    var result = <String, Object>{'argumentName': argumentName};

    var parts = _extractParts(pattern);
    // Looking for (key block)+ sequence. One of the keys has to be "other".
    var pos = 0;
    while (pos < parts.length) {
      var thePart = parts.elementAt(pos);
      var key = thePart._value;

      pos++;
      _checkAndThrow(
          pos < parts.length, 'Missing or invalid select value element.');
      thePart = parts.elementAt(pos);

      Queue<_BlockTypeAndVal>? value;
      if (_ElementType.block == thePart._type) {
        value = _parseBlock(thePart._value);
      } else {
        _checkAndThrow(false, 'Expected block type.');
      }
      result[key.replaceAll(RegExp('\\s'), '')] = value!;
      pos++;
    }

    _checkAndThrow(
        result.containsKey(_other), 'Missing other key in select statement.');
    return result;
  }

  /// Parses a plural type of a block and produces an object for it.
  ///
  /// The [pattern] is the sub-pattern that needs to be parsed as plural.
  /// and returns an bject with plural block info.
  Map<String, Object> _parsePluralBlock(String pattern) {
    var argumentName = '';
    var argumentOffset = 0;
    var replaceRegex = _pluralBlockRe;
    pattern = pattern.replaceFirstMapped(replaceRegex, (match) {
      // string, name, offset
      argumentName = match.group(1)!;
      if (_isDef(match.group(2))) {
        argumentOffset = int.parse(match.group(2)!);
      }
      return '';
    });

    var result = {
      'argumentName': argumentName,
      'argumentOffset': argumentOffset
    };

    var parts = _extractParts(pattern);
    // Looking for (key block)+ sequence.
    var pos = 0;
    while (pos < parts.length) {
      var thePart = parts.elementAt(pos);
      var key = thePart._value;

      pos++;
      _checkAndThrow(
          pos < parts.length, 'Missing or invalid plural value element.');
      thePart = parts.elementAt(pos);

      Queue<_BlockTypeAndVal>? value;
      if (_ElementType.block == thePart._type) {
        value = _parseBlock(thePart._value);
      } else {
        _checkAndThrow(false, 'Expected block type.');
      }
      key = key.replaceFirstMapped(RegExp('\\s*(?:=)?(\\w+)\\s*'), (match) {
        return match.group(1).toString();
      });
      result[key] = value!;
      pos++;
    }

    _checkAndThrow(
        result.containsKey(_other), 'Missing other key in plural statement.');

    return result;
  }

  /// Parses an ordinal type of a block and produces an object for it.
  ///
  /// For example the input string:
  ///  `{FOO, selectordinal, one {Message A}other {Message B}}`
  /// Should result in the output object:
  /// ```
  /// {
  ///   argumentName: 'FOO',
  ///   argumentOffest: 0,
  ///   one: [ { type: 4, value: 'Message A' } ],
  ///   other: [ { type: 4, value: 'Message B' } ]
  /// }
  /// ```
  /// The [pattern] is the sub-pattern that needs to be parsed as ordinal,
  /// and returns an bject with ordinal block info.
  Map<String, Object> _parseOrdinalBlock(String pattern) {
    var argumentName = '';
    var replaceRegex = _ordinalBlockRe;
    pattern = pattern.replaceFirstMapped(replaceRegex, (match) {
      // string, name
      argumentName = match.group(1)!;
      return '';
    });

    var result = {'argumentName': argumentName, 'argumentOffset': 0};

    var parts = _extractParts(pattern);
    // Looking for (key block)+ sequence.
    var pos = 0;
    while (pos < parts.length) {
      var thePart = parts.elementAt(pos);
      var key = thePart._value;

      pos++;
      _checkAndThrow(
          pos < parts.length, 'Missing or invalid ordinal value element.');
      thePart = parts.elementAt(pos);

      Queue<_BlockTypeAndVal>? value;
      if (_ElementType.block == thePart._type) {
        value = _parseBlock(thePart._value);
      } else {
        _checkAndThrow(false, 'Expected block type.');
      }
      key = key.replaceFirstMapped(RegExp('\\s*(?:=)?(\\w+)\\s*'), (match) {
        return match.group(1).toString();
      });
      result[key] = value!;
      pos++;
    }

    _checkAndThrow(result.containsKey(_other),
        'Missing other key in selectordinal statement.');

    return result;
  }

  /// Builds a placeholder from the last index of the array.
  ///
  /// using all the [literals] encountered during parse.
  /// It returns a string that looks like this: `"\uFDDF_" + last index + "_"`.
  String _buildPlaceholder(Queue<String> literals) {
    _checkAndThrow(literals.isNotEmpty, 'Literal array is empty.');

    var index = (literals.length - 1).toString();
    return '$_literalPlaceholder${index}_';
  }
}

//========== EXTRAS: temporary, to help the move from JS to Dart ==========

// Simple goog.isDef replacement, will probably remove it
bool _isDef(Object? obj) {
  return obj != null;
}

// Closure calls assert, which actually ends up with an exception on can catch.
// In Dart assert is only for debug, so I am using this small wrapper method.
void _checkAndThrow(bool condition, String message) {
  if (!condition) {
    throw AssertionError(message);
  }
}

// Dart has no support for ordinals
// TODO(b/142132665): add ordinal rules to intl, then fix this
class _OrdinalRules {
  static String select(num n, String locale) {
    return _PluralRules.select(n, locale);
  }
}

// Simple mapping from Intl.pluralLogic to _PluralRules, to change later
class _PluralRules {
  static String select(num n, String locale) {
    return Intl.pluralLogic(n,
        zero: 'zero',
        one: 'one',
        two: 'two',
        few: 'few',
        many: 'many',
        other: 'other',
        locale: locale,
        useExplicitNumberCases: false);
  }
}

// Pairs a value and information about its type.
class _TypeAndVal<T, V> {
  final T _type;
  final V _value;

  _TypeAndVal(var this._type, var this._value);

  @override
  String toString() {
    return '{type:$_type, value:$_value}';
  }
}

/// Marks a string and block during parsing.
enum _ElementType { string, block }

class _ElementTypeAndVal extends _TypeAndVal<_ElementType, String> {
  _ElementTypeAndVal(var type, var value) : super(type, value);
}

/// Block type.
enum _BlockType { plural, ordinal, select, simple, string, unknown }

class _BlockTypeAndVal extends _TypeAndVal<_BlockType, Object> {
  _BlockTypeAndVal(var type, var value) : super(type, value);
}
