// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/glfw/system_utils.h"

#include <cstdlib>
#include <sstream>

namespace flutter {

namespace {

const char* GetLocaleStringFromEnvironment() {
  const char* retval;
  retval = getenv("LANGUAGE");
  if ((retval != NULL) && (retval[0] != '\0')) {
    return retval;
  }
  retval = getenv("LC_ALL");
  if ((retval != NULL) && (retval[0] != '\0')) {
    return retval;
  }
  retval = getenv("LC_MESSAGES");
  if ((retval != NULL) && (retval[0] != '\0')) {
    return retval;
  }
  retval = getenv("LANG");
  if ((retval != NULL) && (retval[0] != '\0')) {
    return retval;
  }

  return NULL;
}

// The least specific to most specific components of a locale.
enum Component {
  kCodeset = 1 << 0,
  kTerritory = 1 << 1,
  kModifier = 1 << 2,
};

// Construct a mask indicating which of the components in |info| are set.
int ComputeVariantMask(const LanguageInfo& info) {
  int mask = 0;
  if (!info.territory.empty()) {
    mask |= kTerritory;
  }
  if (!info.codeset.empty()) {
    mask |= kCodeset;
  }
  if (!info.modifier.empty()) {
    mask |= kModifier;
  }
  return mask;
}

// Appends most specific to least specific variants of |info| to |languages|.
// For example, "de_DE@euro" would append "de_DE@euro", "de@euro", "de_DE",
// and "de".
void AppendLocaleVariants(std::vector<LanguageInfo>& languages,
                          LanguageInfo info) {
  int mask = ComputeVariantMask(info);
  for (int i = mask; i >= 0; --i) {
    if ((i & ~mask) == 0) {
      LanguageInfo variant;
      variant.language = info.language;

      if (i & kTerritory) {
        variant.territory = info.territory;
      }
      if (i & kCodeset) {
        variant.codeset = info.codeset;
      }
      if (i & kModifier) {
        variant.modifier = info.modifier;
      }
      languages.push_back(variant);
    }
  }
}

// Parses a locale into its components.
LanguageInfo ParseLocale(const std::string& locale) {
  // Locales are of the form "language[_territory][.codeset][@modifier]"
  LanguageInfo result;
  std::string::size_type end = locale.size();
  std::string::size_type modifier_pos = locale.rfind('@');
  if (modifier_pos != std::string::npos) {
    result.modifier = locale.substr(modifier_pos + 1, end - modifier_pos - 1);
    end = modifier_pos;
  }

  std::string::size_type codeset_pos = locale.rfind('.', end);
  if (codeset_pos != std::string::npos) {
    result.codeset = locale.substr(codeset_pos + 1, end - codeset_pos - 1);
    end = codeset_pos;
  }

  std::string::size_type territory_pos = locale.rfind('_', end);
  if (territory_pos != std::string::npos) {
    result.territory =
        locale.substr(territory_pos + 1, end - territory_pos - 1);
    end = territory_pos;
  }

  result.language = locale.substr(0, end);

  return result;
}

}  // namespace

std::vector<LanguageInfo> GetPreferredLanguageInfo() {
  const char* locale_string;
  locale_string = GetLocaleStringFromEnvironment();
  if (!locale_string || locale_string[0] == '\0') {
    // This is the default locale if none is specified according to ISO C.
    locale_string = "C";
  }
  std::istringstream locales_stream(locale_string);
  std::vector<LanguageInfo> languages;
  std::string s;
  while (getline(locales_stream, s, ':')) {
    LanguageInfo info = ParseLocale(s);
    AppendLocaleVariants(languages, info);
  }
  return languages;
}

std::vector<FlutterLocale> ConvertToFlutterLocale(
    const std::vector<LanguageInfo>& languages) {
  std::vector<FlutterLocale> flutter_locales;
  flutter_locales.reserve(languages.size());
  for (const auto& info : languages) {
    FlutterLocale locale = {};
    locale.struct_size = sizeof(FlutterLocale);
    locale.language_code = info.language.c_str();
    if (!info.territory.empty()) {
      locale.country_code = info.territory.c_str();
    }
    if (!info.codeset.empty()) {
      locale.script_code = info.codeset.c_str();
    }
    if (!info.modifier.empty()) {
      locale.variant_code = info.modifier.c_str();
    }
    flutter_locales.push_back(locale);
  }

  return flutter_locales;
}

}  // namespace flutter
