// Copyright (c) 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 "ash/test/test_session_state_delegate.h"

#include <algorithm>
#include <string>

#include "ash/session/user_info.h"
#include "ash/shell.h"
#include "ash/system/user/login_status.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {
namespace test {

namespace {

// The the "canonicalized" user ID from a given |email| address.
std::string GetUserIDFromEmail(const std::string& email) {
  std::string user_id = email;
  std::transform(user_id.begin(), user_id.end(), user_id.begin(), ::tolower);
  return user_id;
}

}  // namespace

class MockUserInfo : public UserInfo {
 public:
  explicit MockUserInfo(const std::string& id) : email_(id) {}
  virtual ~MockUserInfo() {}

  void SetUserImage(const gfx::ImageSkia& user_image) {
    user_image_ = user_image;
  }

  virtual base::string16 GetDisplayName() const OVERRIDE {
    return base::UTF8ToUTF16("Über tray Über tray Über tray Über tray");
  }

  virtual base::string16 GetGivenName() const OVERRIDE {
    return base::UTF8ToUTF16("Über Über Über Über");
  }

  virtual std::string GetEmail() const OVERRIDE { return email_; }

  virtual std::string GetUserID() const OVERRIDE {
    return GetUserIDFromEmail(GetEmail());
  }

  virtual const gfx::ImageSkia& GetImage() const OVERRIDE {
    return user_image_;
  }

  // A test user image.
  gfx::ImageSkia user_image_;

  std::string email_;

  DISALLOW_COPY_AND_ASSIGN(MockUserInfo);
};

TestSessionStateDelegate::TestSessionStateDelegate()
    : has_active_user_(false),
      active_user_session_started_(false),
      can_lock_screen_(true),
      should_lock_screen_before_suspending_(false),
      screen_locked_(false),
      user_adding_screen_running_(false),
      logged_in_users_(1),
      active_user_index_(0) {
  user_list_.push_back(
      new MockUserInfo("First@tray"));  // This is intended to be capitalized.
  user_list_.push_back(
      new MockUserInfo("Second@tray"));  // This is intended to be capitalized.
  user_list_.push_back(new MockUserInfo("third@tray"));
  user_list_.push_back(new MockUserInfo("someone@tray"));
}

TestSessionStateDelegate::~TestSessionStateDelegate() {
  STLDeleteElements(&user_list_);
}

void TestSessionStateDelegate::AddUser(const std::string user_id) {
  user_list_.push_back(new MockUserInfo(user_id));
}

const UserInfo* TestSessionStateDelegate::GetActiveUserInfo() const {
  return user_list_[active_user_index_];
}

content::BrowserContext*
TestSessionStateDelegate::GetBrowserContextByIndex(
    MultiProfileIndex index) {
  return NULL;
}

content::BrowserContext*
TestSessionStateDelegate::GetBrowserContextForWindow(
    aura::Window* window) {
  return NULL;
}

int TestSessionStateDelegate::GetMaximumNumberOfLoggedInUsers() const {
  return 3;
}

int TestSessionStateDelegate::NumberOfLoggedInUsers() const {
  // TODO(skuhne): Add better test framework to test multiple profiles.
  return has_active_user_ ? logged_in_users_ : 0;
}

bool TestSessionStateDelegate::IsActiveUserSessionStarted() const {
  return active_user_session_started_;
}

bool TestSessionStateDelegate::CanLockScreen() const {
  return has_active_user_ && can_lock_screen_;
}

bool TestSessionStateDelegate::IsScreenLocked() const {
  return screen_locked_;
}

bool TestSessionStateDelegate::ShouldLockScreenBeforeSuspending() const {
  return should_lock_screen_before_suspending_;
}

void TestSessionStateDelegate::LockScreen() {
  if (CanLockScreen())
    screen_locked_ = true;
}

void TestSessionStateDelegate::UnlockScreen() {
  screen_locked_ = false;
}

bool TestSessionStateDelegate::IsUserSessionBlocked() const {
  return !IsActiveUserSessionStarted() || IsScreenLocked() ||
      user_adding_screen_running_;
}

SessionStateDelegate::SessionState TestSessionStateDelegate::GetSessionState()
    const {
  if (user_adding_screen_running_)
    return SESSION_STATE_LOGIN_SECONDARY;

  // Assuming that if session is not active we're at login.
  return IsActiveUserSessionStarted() ?
      SESSION_STATE_ACTIVE : SESSION_STATE_LOGIN_PRIMARY;
}

void TestSessionStateDelegate::SetHasActiveUser(bool has_active_user) {
  has_active_user_ = has_active_user;
  if (!has_active_user)
    active_user_session_started_ = false;
  else
    Shell::GetInstance()->ShowShelf();
}

void TestSessionStateDelegate::SetActiveUserSessionStarted(
    bool active_user_session_started) {
  active_user_session_started_ = active_user_session_started;
  if (active_user_session_started) {
    has_active_user_ = true;
    Shell::GetInstance()->CreateShelf();
    Shell::GetInstance()->UpdateAfterLoginStatusChange(
        user::LOGGED_IN_USER);
  }
}

void TestSessionStateDelegate::SetCanLockScreen(bool can_lock_screen) {
  can_lock_screen_ = can_lock_screen;
}

void TestSessionStateDelegate::SetShouldLockScreenBeforeSuspending(
    bool should_lock) {
  should_lock_screen_before_suspending_ = should_lock;
}

void TestSessionStateDelegate::SetUserAddingScreenRunning(
    bool user_adding_screen_running) {
  user_adding_screen_running_ = user_adding_screen_running;
}

void TestSessionStateDelegate::SetUserImage(
    const gfx::ImageSkia& user_image) {
  user_list_[active_user_index_]->SetUserImage(user_image);
}

const UserInfo* TestSessionStateDelegate::GetUserInfo(
    MultiProfileIndex index) const {
  int max = static_cast<int>(user_list_.size());
  return user_list_[index < max ? index : max - 1];
}

const UserInfo* TestSessionStateDelegate::GetUserInfo(
    content::BrowserContext* context) const {
  return user_list_[active_user_index_];
}

bool TestSessionStateDelegate::ShouldShowAvatar(aura::Window* window) const {
  return !GetActiveUserInfo()->GetImage().isNull();
}

void TestSessionStateDelegate::SwitchActiveUser(const std::string& user_id) {
  // Make sure this is a user id and not an email address.
  EXPECT_EQ(user_id, GetUserIDFromEmail(user_id));
  active_user_index_ = 0;
  for (std::vector<MockUserInfo*>::iterator iter = user_list_.begin();
       iter != user_list_.end();
       ++iter) {
    if ((*iter)->GetUserID() == user_id) {
      active_user_index_ = iter - user_list_.begin();
      return;
    }
  }
  NOTREACHED() << "Unknown user:" << user_id;
}

void TestSessionStateDelegate::CycleActiveUser(CycleUser cycle_user) {
  SwitchActiveUser("someone@tray");
}

void TestSessionStateDelegate::AddSessionStateObserver(
    SessionStateObserver* observer) {
}

void TestSessionStateDelegate::RemoveSessionStateObserver(
    SessionStateObserver* observer) {
}

}  // namespace test
}  // namespace ash
