// Copyright 2013 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/ui/ash/multi_user/multi_user_context_menu.h"

#include "ash/multi_profile_uma.h"
#include "ash/session/session_state_delegate.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_warning_dialog.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/account_id/account_id.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h"

namespace chromeos {

namespace {

class MultiUserContextMenuChromeos : public ui::SimpleMenuModel,
                                     public ui::SimpleMenuModel::Delegate {
 public:
  explicit MultiUserContextMenuChromeos(aura::Window* window);
  ~MultiUserContextMenuChromeos() override {}

  // SimpleMenuModel::Delegate:
  bool IsCommandIdChecked(int command_id) const override { return false; }
  bool IsCommandIdEnabled(int command_id) const override { return true; }
  bool GetAcceleratorForCommandId(int command_id,
                                  ui::Accelerator* accelerator) override {
    return false;
  }
  void ExecuteCommand(int command_id, int event_flags) override;

 private:
  // The window for which this menu is.
  aura::Window* window_;

  DISALLOW_COPY_AND_ASSIGN(MultiUserContextMenuChromeos);
};

MultiUserContextMenuChromeos::MultiUserContextMenuChromeos(aura::Window* window)
    : ui::SimpleMenuModel(this),
      window_(window) {
}

void MultiUserContextMenuChromeos::ExecuteCommand(int command_id,
                                                  int event_flags) {
  ExecuteVisitDesktopCommand(command_id, window_);
}
}  // namespace
}  // namespace chromeos

scoped_ptr<ui::MenuModel> CreateMultiUserContextMenu(aura::Window* window) {
  scoped_ptr<ui::MenuModel> model;
  ash::SessionStateDelegate* delegate =
      ash::Shell::GetInstance()->session_state_delegate();
  if (!delegate)
    return model;

  int logged_in_users = delegate->NumberOfLoggedInUsers();
  if (logged_in_users > 1) {
    // If this window is not owned, we don't show the menu addition.
    chrome::MultiUserWindowManager* manager =
        chrome::MultiUserWindowManager::GetInstance();
    const AccountId& account_id = manager->GetWindowOwner(window);
    if (!account_id.is_valid() || !window)
      return model;
    chromeos::MultiUserContextMenuChromeos* menu =
        new chromeos::MultiUserContextMenuChromeos(window);
    model.reset(menu);
    for (int user_index = 1; user_index < logged_in_users; ++user_index) {
      const user_manager::UserInfo* user_info =
          delegate->GetUserInfo(user_index);
      menu->AddItem(user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2
                                    : IDC_VISIT_DESKTOP_OF_LRU_USER_3,
                    l10n_util::GetStringFUTF16(
                        IDS_VISIT_DESKTOP_OF_LRU_USER,
                        user_info->GetDisplayName(),
                        base::ASCIIToUTF16(user_info->GetEmail())));
    }
  }
  return model;
}

void OnAcceptTeleportWarning(const AccountId& account_id,
                             aura::Window* window_,
                             bool no_show_again) {
  PrefService* pref = ProfileManager::GetActiveUserProfile()->GetPrefs();
  pref->SetBoolean(prefs::kMultiProfileWarningShowDismissed, no_show_again);

  ash::MultiProfileUMA::RecordTeleportAction(
      ash::MultiProfileUMA::TELEPORT_WINDOW_CAPTION_MENU);

  chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(window_,
                                                                   account_id);
}

void ExecuteVisitDesktopCommand(int command_id, aura::Window* window) {
  switch (command_id) {
    case IDC_VISIT_DESKTOP_OF_LRU_USER_2:
    case IDC_VISIT_DESKTOP_OF_LRU_USER_3: {
      // When running the multi user mode on Chrome OS, windows can "visit"
      // another user's desktop.
      const AccountId account_id =
          ash::Shell::GetInstance()
              ->session_state_delegate()
              ->GetUserInfo(IDC_VISIT_DESKTOP_OF_LRU_USER_2 == command_id ? 1
                                                                          : 2)
              ->GetAccountId();
      base::Callback<void(bool)> on_accept =
          base::Bind(&OnAcceptTeleportWarning, account_id, window);

      // Don't show warning dialog if any logged in user in multi-profiles
      // session dismissed it.
      const user_manager::UserList logged_in_users =
          user_manager::UserManager::Get()->GetLoggedInUsers();
      for (user_manager::UserList::const_iterator it = logged_in_users.begin();
           it != logged_in_users.end();
           ++it) {
        if (multi_user_util::GetProfileFromAccountId((*it)->GetAccountId())
                ->GetPrefs()
                ->GetBoolean(prefs::kMultiProfileWarningShowDismissed)) {
          bool active_user_show_option =
              ProfileManager::GetActiveUserProfile()->
              GetPrefs()->GetBoolean(prefs::kMultiProfileWarningShowDismissed);
          on_accept.Run(active_user_show_option);
          return;
        }
      }
      chromeos::ShowMultiprofilesWarningDialog(on_accept);
      return;
    }
    default:
      NOTREACHED();
  }
}