// Copyright (c) 2012 The Chromium 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 "chrome/browser/chromeos/locale_change_guard.h"

#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"

using base::UserMetricsAction;
using content::WebContents;

namespace chromeos {

LocaleChangeGuard::LocaleChangeGuard(Profile* profile)
    : profile_(profile),
      reverted_(false),
      session_started_(false),
      main_frame_loaded_(false) {
  DCHECK(profile_);
  registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
                 content::NotificationService::AllSources());
}

LocaleChangeGuard::~LocaleChangeGuard() {}

void LocaleChangeGuard::OnLogin() {
  registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
                 content::NotificationService::AllBrowserContextsAndSources());
}

void LocaleChangeGuard::RevertLocaleChange() {
  if (profile_ == NULL ||
      from_locale_.empty() ||
      to_locale_.empty()) {
    NOTREACHED();
    return;
  }
  if (reverted_)
    return;
  reverted_ = true;
  content::RecordAction(UserMetricsAction("LanguageChange_Revert"));
  profile_->ChangeAppLocale(
      from_locale_, Profile::APP_LOCALE_CHANGED_VIA_REVERT);
  chrome::AttemptUserExit();
}

void LocaleChangeGuard::RevertLocaleChangeCallback(
    const base::ListValue* list) {
  RevertLocaleChange();
}

void LocaleChangeGuard::Observe(int type,
                                const content::NotificationSource& source,
                                const content::NotificationDetails& details) {
  if (profile_ == NULL) {
    NOTREACHED();
    return;
  }
  switch (type) {
    case chrome::NOTIFICATION_SESSION_STARTED: {
      session_started_ = true;
      registrar_.Remove(this, chrome::NOTIFICATION_SESSION_STARTED,
                        content::NotificationService::AllSources());
      if (main_frame_loaded_)
        Check();
      break;
    }
    case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
      if (profile_ ==
          content::Source<WebContents>(source)->GetBrowserContext()) {
        main_frame_loaded_ = true;
        // We need to perform locale change check only once, so unsubscribe.
        registrar_.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
                          content::NotificationService::AllSources());
        if (session_started_)
          Check();
      }
      break;
    }
    case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: {
      if (DeviceSettingsService::Get()->HasPrivateOwnerKey()) {
        PrefService* local_state = g_browser_process->local_state();
        if (local_state) {
          PrefService* prefs = profile_->GetPrefs();
          if (prefs == NULL) {
            NOTREACHED();
            return;
          }
          std::string owner_locale =
              prefs->GetString(prefs::kApplicationLocale);
          if (!owner_locale.empty())
            local_state->SetString(prefs::kOwnerLocale, owner_locale);
        }
      }
      break;
    }
    default: {
      NOTREACHED();
      break;
    }
  }
}

void LocaleChangeGuard::Check() {
  std::string cur_locale = g_browser_process->GetApplicationLocale();
  if (cur_locale.empty()) {
    NOTREACHED();
    return;
  }

  PrefService* prefs = profile_->GetPrefs();
  if (prefs == NULL) {
    NOTREACHED();
    return;
  }

  std::string to_locale = prefs->GetString(prefs::kApplicationLocale);
  if (to_locale != cur_locale) {
    // This conditional branch can occur in cases like:
    // (1) kApplicationLocale preference was modified by synchronization;
    // (2) kApplicationLocale is managed by policy.
    return;
  }

  std::string from_locale = prefs->GetString(prefs::kApplicationLocaleBackup);
  if (from_locale.empty() || from_locale == to_locale)
    return;  // No locale change was detected, just exit.

  if (prefs->GetString(prefs::kApplicationLocaleAccepted) == to_locale)
    return;  // Already accepted.

  // Locale change detected, showing notification.
  if (from_locale_ != from_locale || to_locale_ != to_locale) {
    // Falling back to showing message in current locale.
    LOG(ERROR) <<
        "Showing locale change notification in current (not previous) language";
    PrepareChangingLocale(from_locale, to_locale);
  }

  ash::Shell::GetInstance()->system_tray_notifier()->NotifyLocaleChanged(
      this, cur_locale, from_locale_, to_locale_);
}

void LocaleChangeGuard::AcceptLocaleChange() {
  if (profile_ == NULL ||
      from_locale_.empty() ||
      to_locale_.empty()) {
    NOTREACHED();
    return;
  }

  // Check whether locale has been reverted or changed.
  // If not: mark current locale as accepted.
  if (reverted_)
    return;
  PrefService* prefs = profile_->GetPrefs();
  if (prefs == NULL) {
    NOTREACHED();
    return;
  }
  if (prefs->GetString(prefs::kApplicationLocale) != to_locale_)
    return;
  content::RecordAction(UserMetricsAction("LanguageChange_Accept"));
  prefs->SetString(prefs::kApplicationLocaleBackup, to_locale_);
  prefs->SetString(prefs::kApplicationLocaleAccepted, to_locale_);
}

void LocaleChangeGuard::PrepareChangingLocale(
    const std::string& from_locale, const std::string& to_locale) {
  std::string cur_locale = g_browser_process->GetApplicationLocale();
  if (!from_locale.empty())
    from_locale_ = from_locale;
  if (!to_locale.empty())
    to_locale_ = to_locale;

  if (!from_locale_.empty() && !to_locale_.empty()) {
    base::string16 from = l10n_util::GetDisplayNameForLocale(
        from_locale_, cur_locale, true);
    base::string16 to = l10n_util::GetDisplayNameForLocale(
        to_locale_, cur_locale, true);

    title_text_ = l10n_util::GetStringUTF16(
        IDS_OPTIONS_SETTINGS_SECTION_TITLE_LANGUAGE);
    message_text_ = l10n_util::GetStringFUTF16(
        IDS_LOCALE_CHANGE_MESSAGE, from, to);
    revert_link_text_ = l10n_util::GetStringFUTF16(
        IDS_LOCALE_CHANGE_REVERT_MESSAGE, from);
  }
}

}  // namespace chromeos
