// 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.
// @dart=2.9

import 'package:intl/src/locale.dart' show Locale;

import 'locale_deprecations.dart';
import 'locale_extensions.dart';

/// The primary implementation of the Locale interface.
class LocaleImplementation extends Locale {
  /// Simple private constructor with asserts to check invariants.
  LocaleImplementation._(this.languageCode, this.scriptCode, this.countryCode,
      this.variants, this._extensions) {
    // Debug-mode asserts to ensure all parameters are normalized and UTS #35
    // compliant.
    assert(
        languageCode != null && _normalizedLanguageRE.hasMatch(languageCode),
        'languageCode must match RegExp/${_normalizedLanguageRE.pattern}/ '
        'but is "$languageCode".');
    assert(
        scriptCode == null || _normalizedScriptRE.hasMatch(scriptCode),
        'scriptCode must match RegExp/${_normalizedScriptRE.pattern}/ '
        'but is "$scriptCode".');
    assert(
        countryCode == null || _normalizedRegionRE.hasMatch(countryCode),
        'countryCode must match RegExp/${_normalizedRegionRE.pattern}/ '
        'but is "$countryCode".');
    assert(
        variants is List<String> &&
            variants.every(_normalizedVariantRE.hasMatch),
        'each variant must match RegExp/${_normalizedVariantRE.pattern}/ '
        'but variants are "$variants".');
  }

  /// For debug/assert-use only! Matches subtags considered valid for
  /// [languageCode], does not imply subtag is valid as per Unicode LDML spec!
  //
  // Must be static to get tree-shaken away in production code.
  static final _normalizedLanguageRE = RegExp(r'^[a-z]{2,3}$|^[a-z]{5,8}$');

  /// For debug/assert-use only! Matches subtags considered valid for
  /// [scriptCode], does not imply subtag is valid as per Unicode LDML spec!
  //
  // Must be static to get tree-shaken away in production code.
  static final _normalizedScriptRE = RegExp(r'^[A-Z][a-z]{3}$');

  /// For debug/assert-use only! Matches subtags considered valid for
  /// [countryCode], does not imply subtags are valid as per Unicode LDML spec!
  //
  // Must be static to get tree-shaken away in production code.
  static final _normalizedRegionRE = RegExp(r'^[A-Z]{2}$|^\d{3}$');

  /// For debug/assert-use only! Matches subtags considered valid for
  /// [variants], does not imply subtags are valid as per Unicode LDML spec!
  //
  // Must be static to get tree-shaken away in production code.
  static final _normalizedVariantRE = RegExp(r'^[a-z\d]{5,8}$|^\d[a-z\d]{3}$');

  /// Simple factory which assumes parameters are syntactically correct.
  ///
  /// In debug mode, incorrect use may result in an assertion failure. (In
  /// production code, this class makes no promises regarding the consequence of
  /// incorrect use.)
  ///
  /// For public APIs, see [Locale.fromSubtags] and [Locale.parse].
  factory LocaleImplementation.unsafe(
    String languageCode, {
    String scriptCode,
    String countryCode,
    Iterable<String> variants,
    LocaleExtensions extensions,
  }) {
    variants = (variants != null && variants.isNotEmpty)
        ? List.unmodifiable(variants.toList()..sort())
        : const [];
    return LocaleImplementation._(
        languageCode, scriptCode, countryCode, variants, extensions);
  }

  /// Constructs a Locale instance that consists of only language, region and
  /// country subtags.
  ///
  /// Throws a [FormatException] if any subtag is syntactically invalid.
  static LocaleImplementation fromSubtags(
      {String languageCode, String scriptCode, String countryCode}) {
    return LocaleImplementation._(
        replaceDeprecatedLanguageSubtag(_normalizeLanguageCode(languageCode)),
        _normalizeScriptCode(scriptCode),
        replaceDeprecatedRegionSubtag(_normalizeCountryCode(countryCode)),
        const [],
        null);
  }

  /// Performs case normalization on `languageCode`.
  ///
  /// Throws a [FormatException] if it is syntactically invalid.
  static String _normalizeLanguageCode(String languageCode) {
    if (!_languageRexExp.hasMatch(languageCode)) {
      throw FormatException('Invalid language "$languageCode"');
    }
    return languageCode.toLowerCase();
  }

  static final _languageRexExp = RegExp(r'^[a-zA-Z]{2,3}$|^[a-zA-Z]{5,8}$');

  /// Performs case normalization on `scriptCode`.
  ///
  /// Throws a [FormatException] if it is syntactically invalid.
  static String _normalizeScriptCode(String scriptCode) {
    if (scriptCode == null) return null;
    if (!_scriptRegExp.hasMatch(scriptCode)) {
      throw FormatException('Invalid script "$scriptCode"');
    }
    return toCapCase(scriptCode);
  }

  static final _scriptRegExp = RegExp(r'^[a-zA-Z]{4}$');

  /// Performs case normalization on `countryCode`.
  ///
  /// Throws a [FormatException] if it is syntactically invalid.
  static String _normalizeCountryCode(String countryCode) {
    if (countryCode == null) return null;
    if (!_regionRegExp.hasMatch(countryCode)) {
      throw FormatException('Invalid region "$countryCode"');
    }
    return countryCode.toUpperCase();
  }

  static final _regionRegExp = RegExp(r'^[a-zA-Z]{2}$|^\d{3}$');

  /// The language subtag of the Locale Identifier.
  ///
  /// It is syntactically valid, normalized (has correct case) and canonical
  /// (deprecated tags have been replaced), but not necessarily valid (the
  /// language might not exist) because the list of valid languages changes with
  /// time.
  final String languageCode;

  /// The script subtag of the Locale Identifier, null if absent.
  ///
  /// It is syntactically valid, normalized (has correct case) and canonical
  /// (deprecated tags have been replaced), but not necessarily valid (the
  /// script might not exist) because the list of valid scripts changes with
  /// time.
  final String scriptCode;

  /// The region subtag of the Locale Identifier, null if absent.
  ///
  /// It is syntactically valid, normalized (has correct case) and canonical
  /// (deprecated tags have been replaced), but not necessarily valid (the
  /// region might not exist) because the list of valid regions changes with
  /// time.
  final String countryCode;

  /// Iterable of variant subtags, zero-length iterable if variants are absent.
  ///
  /// They are syntactically valid, normalized (have correct case) and canonical
  /// (sorted alphabetically and deprecated tags have been replaced) but not
  /// necessarily valid (variants might not exist) because the list of variants
  /// changes with time.
  final Iterable<String> variants;

  /// Locale extensions, null if the locale has no extensions.
  // TODO(hugovdm): Not yet supported: getters for extensions.
  final LocaleExtensions _extensions;

  /// Cache of the value returned by [toLanguageTag].
  String _languageTag;

  /// Returns the canonical Unicode BCP47 Locale Identifier for this locale.
  String toLanguageTag() {
    if (_languageTag == null) {
      final out = [languageCode];
      if (scriptCode != null) out.add(scriptCode);
      if (countryCode != null) out.add(countryCode);
      out.addAll(variants);
      if (_extensions != null) out.addAll(_extensions.subtags);
      _languageTag = out.join('-');
    }
    return _languageTag;
  }
}

/// Returns `input` with first letter capitalized and the rest lowercase.
String toCapCase(String input) =>
    '${input[0].toUpperCase()}${input.substring(1).toLowerCase()}';
