// 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.

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 &&
            variants.every((v) => _normalizedVariantRE.hasMatch(v)),
        '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 List<String> 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()}';
