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

#include "chrome/browser/themes/theme_service_aura_linux.h"

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/custom_theme_supplier.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "ui/color/system_theme.h"
#include "ui/gfx/image/image.h"
#include "ui/linux/linux_ui.h"
#include "ui/linux/linux_ui_factory.h"
#include "ui/native_theme/native_theme_aura.h"

namespace {

ui::SystemTheme ValidateSystemTheme(ui::SystemTheme system_theme) {
  switch (system_theme) {
    case ui::SystemTheme::kDefault:
#if BUILDFLAG(IS_LINUX)
    case ui::SystemTheme::kGtk:
    case ui::SystemTheme::kQt:
#endif
      return system_theme;
    default:
      return ui::SystemTheme::kDefault;
  }
}

class SystemThemeLinux : public CustomThemeSupplier {
 public:
  SystemThemeLinux(PrefService* pref_service, ui::LinuxUiTheme* linux_ui_theme);

  SystemThemeLinux(const SystemThemeLinux&) = delete;
  SystemThemeLinux& operator=(const SystemThemeLinux&) = delete;

  // Overridden from CustomThemeSupplier:
  void StartUsingTheme() override;
  void StopUsingTheme() override;
  bool GetColor(int id, SkColor* color) const override;
  bool GetDisplayProperty(int id, int* result) const override;
  gfx::Image GetImageNamed(int id) const override;
  bool HasCustomImage(int id) const override;
  ui::NativeTheme* GetNativeTheme() const override;

 private:
  ~SystemThemeLinux() override;

  // These pointers are not owned by us.
  const raw_ptr<PrefService, DanglingUntriaged> pref_service_;
  const raw_ptr<ui::LinuxUiTheme> linux_ui_theme_;
};

SystemThemeLinux::SystemThemeLinux(PrefService* pref_service,
                                   ui::LinuxUiTheme* linux_ui_theme)
    : CustomThemeSupplier(ThemeType::kNativeX11),
      pref_service_(pref_service),
      linux_ui_theme_(linux_ui_theme) {}

void SystemThemeLinux::StartUsingTheme() {
  pref_service_->SetInteger(
      prefs::kSystemTheme,
      static_cast<int>(linux_ui_theme_->GetNativeTheme()->system_theme()));
  // Have the former theme notify its observers of change.
  ui::NativeTheme::GetInstanceForNativeUi()->NotifyOnNativeThemeUpdated();
}

void SystemThemeLinux::StopUsingTheme() {
  pref_service_->SetInteger(prefs::kSystemTheme,
                            static_cast<int>(ui::SystemTheme::kDefault));
  // Have the former theme notify its observers of change.
  linux_ui_theme_->GetNativeTheme()->NotifyOnNativeThemeUpdated();
}

bool SystemThemeLinux::GetColor(int id, SkColor* color) const {
  return linux_ui_theme_->GetColor(
      id, color, pref_service_->GetBoolean(prefs::kUseCustomChromeFrame));
}

bool SystemThemeLinux::GetDisplayProperty(int id, int* result) const {
  return linux_ui_theme_->GetDisplayProperty(id, result);
}

gfx::Image SystemThemeLinux::GetImageNamed(int id) const {
  return gfx::Image();
}

bool SystemThemeLinux::HasCustomImage(int id) const {
  return false;
}

ui::NativeTheme* SystemThemeLinux::GetNativeTheme() const {
  return linux_ui_theme_->GetNativeTheme();
}

SystemThemeLinux::~SystemThemeLinux() = default;

}  // namespace

ThemeServiceAuraLinux::~ThemeServiceAuraLinux() = default;

ui::SystemTheme ThemeServiceAuraLinux::GetDefaultSystemTheme() const {
  return GetSystemThemeForProfile(profile());
}

void ThemeServiceAuraLinux::UseTheme(ui::SystemTheme system_theme) {
  if (system_theme == ui::SystemTheme::kDefault) {
    UseDefaultTheme();
  } else if (auto* linux_ui_theme = ui::GetLinuxUiTheme(system_theme)) {
    SetCustomDefaultTheme(base::MakeRefCounted<SystemThemeLinux>(
        profile()->GetPrefs(), linux_ui_theme));
  } else {
    return;
  }
  UMA_HISTOGRAM_ENUMERATION("Linux.SystemTheme.Profile", system_theme);
}

void ThemeServiceAuraLinux::UseSystemTheme() {
  if (UsingSystemTheme())
    return;
  if (auto* linux_ui_theme = ui::GetDefaultLinuxUiTheme()) {
    if (auto* native_theme = linux_ui_theme->GetNativeTheme()) {
      UseTheme(native_theme->system_theme());
      return;
    }
  }
  ThemeService::UseSystemTheme();
}

bool ThemeServiceAuraLinux::IsSystemThemeDistinctFromDefaultTheme() const {
  return true;
}

bool ThemeServiceAuraLinux::UsingSystemTheme() const {
  return GetThemeSupplier() &&
         GetThemeSupplier()->get_theme_type() ==
             ui::ColorProviderKey::ThemeInitializerSupplier::ThemeType::
                 kNativeX11;
}

void ThemeServiceAuraLinux::FixInconsistentPreferencesIfNeeded() {
  PrefService* prefs = profile()->GetPrefs();

  // When using the system theme, the theme ID should match the default. Give
  // precedence to the non-default theme specified.
  if (GetThemeID() != ThemeHelper::kDefaultThemeID &&
      prefs->GetInteger(prefs::kSystemTheme) !=
          static_cast<int>(ui::SystemTheme::kDefault)) {
    prefs->SetInteger(prefs::kSystemTheme,
                      static_cast<int>(ui::SystemTheme::kDefault));
  }
}

// static
ui::SystemTheme ThemeServiceAuraLinux::GetSystemThemeForProfile(
    const Profile* profile) {
  if (!profile || profile->IsChild())
    return ui::SystemTheme::kDefault;
  return ValidateSystemTheme(static_cast<ui::SystemTheme>(
      profile->GetPrefs()->GetInteger(prefs::kSystemTheme)));
}
