// 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/windows/system_utils.h"

#include <Windows.h>

#include <sstream>

#include "third_party/cppwinrt/generated/winrt/Windows.Foundation.Collections.h"
#include "third_party/cppwinrt/generated/winrt/Windows.System.UserProfile.h"
#include "third_party/cppwinrt/generated/winrt/Windows.UI.ViewManagement.h"
#include "third_party/cppwinrt/generated/winrt/Windows.UI.h"

#include "flutter/fml/platform/win/wstring_conversion.h"

namespace flutter {

std::vector<LanguageInfo> GetPreferredLanguageInfo() {
  std::vector<std::wstring> languages = GetPreferredLanguages();
  std::vector<LanguageInfo> language_info;
  for (auto language : languages) {
    language_info.push_back(ParseLanguageName(language));
  }
  return language_info;
}

std::vector<std::wstring> GetPreferredLanguages() {
  std::vector<std::wstring> languages;
  auto platform_languages = winrt::Windows::System::UserProfile::
      GlobalizationPreferences::Languages();
  for (const auto& platform_language : platform_languages) {
    languages.push_back(std::wstring{platform_language});
  }
  return languages;
}

LanguageInfo ParseLanguageName(std::wstring language_name) {
  LanguageInfo info;

  // Split by '-', discarding any suplemental language info (-x-foo).
  std::vector<std::string> components;
  std::istringstream stream(fml::WideStringToUtf8(language_name));
  std::string component;
  while (getline(stream, component, '-')) {
    if (component == "x") {
      break;
    }
    components.push_back(component);
  }

  // Determine which components are which.
  info.language = components[0];
  if (components.size() == 3) {
    info.script = components[1];
    info.region = components[2];
  } else if (components.size() == 2) {
    // A script code will always be four characters long.
    if (components[1].size() == 4) {
      info.script = components[1];
    } else {
      info.region = components[1];
    }
  }
  return info;
}

std::wstring GetUserTimeFormat() {
  // Rather than do the call-allocate-call-free dance, just use a sufficiently
  // large buffer to handle any reasonable time format string.
  const int kBufferSize = 100;
  wchar_t buffer[kBufferSize];
  if (::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_STIMEFORMAT, buffer,
                        kBufferSize) == 0) {
    return std::wstring();
  }
  return std::wstring(buffer, kBufferSize);
}

bool Prefer24HourTime(std::wstring time_format) {
  return time_format.find(L"H") != std::wstring::npos;
}

std::wstring GetPreferredBrightness() {
  winrt::Windows::UI::ViewManagement::UISettings ui_settings;
  auto background_color = ui_settings.GetColorValue(
      winrt::Windows::UI::ViewManagement::UIColorType::Background);
  // Assuming that Windows return `Colors::Black` when being dark theme.
  if (background_color == winrt::Windows::UI::Colors::Black()) {
    return kPlatformBrightnessDark;
  } else {
    return kPlatformBrightnessLight;
  }
}

}  // namespace flutter
