// Copyright 2014 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 "components/user_manager/user.h"

#include <stddef.h>

#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/user_manager.h"
#include "google_apis/gaia/gaia_auth_util.h"

namespace user_manager {

namespace {

// Must be in sync with histogram enum UserTypeChanged in enums.xml.
// The values must never be changed (only new ones can be added) as they
// are stored in UMA logs.
enum class UserTypeChangeHistogram {
  UNKNOWN_FATAL = 0,
  REGULAR_TO_CHILD = 1,
  CHILD_TO_REGULAR = 2,
  COUNT,  // Not a value, just a count of other values.
};
void UMAUserTypeChanged(const UserTypeChangeHistogram value) {
  UMA_HISTOGRAM_ENUMERATION("UserManager.UserTypeChanged", value,
                            UserTypeChangeHistogram::COUNT);
}

// Returns account name portion of an email.
std::string GetUserName(const std::string& email) {
  std::string::size_type i = email.find('@');
  if (i == 0 || i == std::string::npos) {
    return email;
  }
  return email.substr(0, i);
}

}  // namespace

// static
bool User::TypeHasGaiaAccount(UserType user_type) {
  return user_type == USER_TYPE_REGULAR ||
         user_type == USER_TYPE_CHILD;
}

// Also used for regular supervised users.
class RegularUser : public User {
 public:
  RegularUser(const AccountId& account_id, const UserType user_type);
  ~RegularUser() override;

  // Overridden from User:
  UserType GetType() const override;
  void UpdateType(UserType user_type) override;
  bool CanSyncImage() const override;

 private:
  bool is_child_;

  DISALLOW_COPY_AND_ASSIGN(RegularUser);
};

class ActiveDirectoryUser : public RegularUser {
 public:
  explicit ActiveDirectoryUser(const AccountId& account_id);
  ~ActiveDirectoryUser() override;
  // Overridden from User:
  UserType GetType() const override;
  bool CanSyncImage() const override;
};

class GuestUser : public User {
 public:
  explicit GuestUser(const AccountId& guest_account_id);
  ~GuestUser() override;

  // Overridden from User:
  UserType GetType() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(GuestUser);
};

class DeviceLocalAccountUserBase : public User {
 public:
  // User:
  bool IsAffiliated() const override;

 protected:
  explicit DeviceLocalAccountUserBase(const AccountId& account_id);
  ~DeviceLocalAccountUserBase() override;
  // User:
  void SetAffiliation(bool) override;
  bool IsDeviceLocalAccount() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountUserBase);
};

class KioskAppUser : public DeviceLocalAccountUserBase {
 public:
  explicit KioskAppUser(const AccountId& kiosk_app_account_id);
  ~KioskAppUser() override;

  // Overridden from User:
  UserType GetType() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(KioskAppUser);
};

class ArcKioskAppUser : public DeviceLocalAccountUserBase {
 public:
  explicit ArcKioskAppUser(const AccountId& arc_kiosk_account_id);
  ~ArcKioskAppUser() override;

  // Overridden from User:
  UserType GetType() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(ArcKioskAppUser);
};

class SupervisedUser : public User {
 public:
  explicit SupervisedUser(const AccountId& account_id);
  ~SupervisedUser() override;

  // Overridden from User:
  UserType GetType() const override;
  std::string display_email() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(SupervisedUser);
};

class PublicAccountUser : public DeviceLocalAccountUserBase {
 public:
  explicit PublicAccountUser(const AccountId& account_id);
  ~PublicAccountUser() override;

  // Overridden from User:
  UserType GetType() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(PublicAccountUser);
};

User::User(const AccountId& account_id)
    : account_id_(account_id), user_image_(new UserImage) {}

User::~User() {}

std::string User::GetDisplayEmail() const {
  return display_email();
}

base::string16 User::GetDisplayName() const {
  // Fallback to the email account name in case display name haven't been set.
  return display_name_.empty() ? base::UTF8ToUTF16(GetAccountName(true))
                               : display_name_;
}

base::string16 User::GetGivenName() const {
  return given_name_;
}

const gfx::ImageSkia& User::GetImage() const {
  return user_image_->image();
}

const AccountId& User::GetAccountId() const {
  return account_id_;
}

void User::UpdateType(UserType user_type) {
  UMAUserTypeChanged(UserTypeChangeHistogram::UNKNOWN_FATAL);
  LOG(FATAL) << "Unsupported user type change " << GetType() << "=>"
             << user_type;
}

bool User::HasGaiaAccount() const {
  return TypeHasGaiaAccount(GetType());
}

bool User::IsActiveDirectoryUser() const {
  return GetType() == user_manager::USER_TYPE_ACTIVE_DIRECTORY;
}

bool User::IsSupervised() const {
  UserType type = GetType();
  return  type == USER_TYPE_SUPERVISED ||
          type == USER_TYPE_CHILD;
}

bool User::IsChild() const {
  return GetType() == USER_TYPE_CHILD;
}

std::string User::GetAccountName(bool use_display_email) const {
  if (use_display_email && !display_email_.empty())
    return GetUserName(display_email_);
  else
    return GetUserName(account_id_.GetUserEmail());
}

bool User::HasDefaultImage() const {
  return UserManager::Get()->IsValidDefaultUserImageId(image_index_);
}

bool User::CanSyncImage() const {
  return false;
}

std::string User::display_email() const {
  return display_email_;
}

bool User::can_lock() const {
  return can_lock_;
}

std::string User::username_hash() const {
  return username_hash_;
}

bool User::is_logged_in() const {
  return is_logged_in_;
}

bool User::is_active() const {
  return is_active_;
}

bool User::has_gaia_account() const {
  static_assert(user_manager::NUM_USER_TYPES == 9,
                "NUM_USER_TYPES should equal 9");
  switch (GetType()) {
    case user_manager::USER_TYPE_REGULAR:
    case user_manager::USER_TYPE_CHILD:
      return true;
    case user_manager::USER_TYPE_GUEST:
    case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
    case user_manager::USER_TYPE_SUPERVISED:
    case user_manager::USER_TYPE_KIOSK_APP:
    case user_manager::USER_TYPE_ARC_KIOSK_APP:
    case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
      return false;
    default:
      NOTREACHED();
  }
  return false;
}

void User::AddProfileCreatedObserver(base::OnceClosure on_profile_created) {
  DCHECK(!profile_is_created_);
  on_profile_created_observers_.push_back(std::move(on_profile_created));
}

bool User::IsAffiliated() const {
  return is_affiliated_;
}

void User::SetProfileIsCreated() {
  profile_is_created_ = true;
  for (auto& callback : on_profile_created_observers_)
    std::move(callback).Run();
  on_profile_created_observers_.clear();
}

void User::SetAffiliation(bool is_affiliated) {
  is_affiliated_ = is_affiliated;
}

bool User::IsDeviceLocalAccount() const {
  return false;
}

User* User::CreateRegularUser(const AccountId& account_id,
                              const UserType user_type) {
  if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY)
    return new ActiveDirectoryUser(account_id);
  return new RegularUser(account_id, user_type);
}

User* User::CreateGuestUser(const AccountId& guest_account_id) {
  return new GuestUser(guest_account_id);
}

User* User::CreateKioskAppUser(const AccountId& kiosk_app_account_id) {
  return new KioskAppUser(kiosk_app_account_id);
}

User* User::CreateArcKioskAppUser(const AccountId& arc_kiosk_account_id) {
  return new ArcKioskAppUser(arc_kiosk_account_id);
}

User* User::CreateSupervisedUser(const AccountId& account_id) {
  return new SupervisedUser(account_id);
}

User* User::CreatePublicAccountUser(const AccountId& account_id) {
  return new PublicAccountUser(account_id);
}

void User::SetAccountLocale(const std::string& resolved_account_locale) {
  account_locale_.reset(new std::string(resolved_account_locale));
}

void User::SetImage(std::unique_ptr<UserImage> user_image, int image_index) {
  user_image_ = std::move(user_image);
  image_index_ = image_index;
  image_is_stub_ = false;
  image_is_loading_ = false;
  DCHECK(HasDefaultImage() || user_image_->has_image_bytes());
}

void User::SetImageURL(const GURL& image_url) {
  user_image_->set_url(image_url);
}

void User::SetStubImage(std::unique_ptr<UserImage> stub_user_image,
                        int image_index,
                        bool is_loading) {
  user_image_ = std::move(stub_user_image);
  image_index_ = image_index;
  image_is_stub_ = true;
  image_is_loading_ = is_loading;
}

UserType ActiveDirectoryUser::GetType() const {
  return user_manager::USER_TYPE_ACTIVE_DIRECTORY;
}

bool ActiveDirectoryUser::CanSyncImage() const {
  return false;
}

RegularUser::RegularUser(const AccountId& account_id, const UserType user_type)
    : User(account_id), is_child_(user_type == USER_TYPE_CHILD) {
  if (user_type != USER_TYPE_CHILD && user_type != USER_TYPE_REGULAR &&
      user_type != USER_TYPE_ACTIVE_DIRECTORY) {
    LOG(FATAL) << "Invalid user type " << user_type;
  }

  set_can_lock(true);
  set_display_email(account_id.GetUserEmail());
}

ActiveDirectoryUser::ActiveDirectoryUser(const AccountId& account_id)
    : RegularUser(account_id, user_manager::USER_TYPE_ACTIVE_DIRECTORY) {}

RegularUser::~RegularUser() {
}

ActiveDirectoryUser::~ActiveDirectoryUser() {}

UserType RegularUser::GetType() const {
  return is_child_ ? user_manager::USER_TYPE_CHILD :
                     user_manager::USER_TYPE_REGULAR;
}

void RegularUser::UpdateType(UserType user_type) {
  const UserType current_type = GetType();
  // Can only change between regular and child.
  if ((user_type == user_manager::USER_TYPE_CHILD ||
       user_type == user_manager::USER_TYPE_REGULAR) &&
      (current_type == user_manager::USER_TYPE_CHILD ||
       current_type == user_manager::USER_TYPE_REGULAR)) {
    // We want all the other type changes to crash, that is why this check is
    // not at the top level.
    if (user_type == current_type)
      return;
    const bool old_is_child = is_child_;
    is_child_ = user_type == user_manager::USER_TYPE_CHILD;
    LOG(WARNING) << "User type has changed: " << current_type
                 << " (is_child=" << old_is_child << ") => " << user_type
                 << " (is_child=" << is_child_ << ")";
    UMAUserTypeChanged(is_child_ ? UserTypeChangeHistogram::REGULAR_TO_CHILD
                                 : UserTypeChangeHistogram::CHILD_TO_REGULAR);
    return;
  }
  // Fail with LOG(FATAL).
  User::UpdateType(user_type);
}

bool RegularUser::CanSyncImage() const {
  return true;
}

GuestUser::GuestUser(const AccountId& guest_account_id)
    : User(guest_account_id) {
  set_display_email(std::string());
}

GuestUser::~GuestUser() {
}

UserType GuestUser::GetType() const {
  return user_manager::USER_TYPE_GUEST;
}

DeviceLocalAccountUserBase::DeviceLocalAccountUserBase(
    const AccountId& account_id) : User(account_id) {
}

DeviceLocalAccountUserBase::~DeviceLocalAccountUserBase() {
}

bool DeviceLocalAccountUserBase::IsAffiliated() const {
  return true;
}

void DeviceLocalAccountUserBase::SetAffiliation(bool) {
  // Device local accounts are always affiliated. No affiliation modification
  // must happen.
  NOTREACHED();
}

bool DeviceLocalAccountUserBase::IsDeviceLocalAccount() const {
  return true;
}

KioskAppUser::KioskAppUser(const AccountId& kiosk_app_account_id)
    : DeviceLocalAccountUserBase(kiosk_app_account_id) {
  set_display_email(kiosk_app_account_id.GetUserEmail());
}

KioskAppUser::~KioskAppUser() {
}

UserType KioskAppUser::GetType() const {
  return user_manager::USER_TYPE_KIOSK_APP;
}

ArcKioskAppUser::ArcKioskAppUser(const AccountId& arc_kiosk_account_id)
    : DeviceLocalAccountUserBase(arc_kiosk_account_id) {
  set_display_email(arc_kiosk_account_id.GetUserEmail());
}

ArcKioskAppUser::~ArcKioskAppUser() {
}

UserType ArcKioskAppUser::GetType() const {
  return user_manager::USER_TYPE_ARC_KIOSK_APP;
}

SupervisedUser::SupervisedUser(const AccountId& account_id) : User(account_id) {
  set_can_lock(true);
}

SupervisedUser::~SupervisedUser() {
}

UserType SupervisedUser::GetType() const {
  return user_manager::USER_TYPE_SUPERVISED;
}

std::string SupervisedUser::display_email() const {
  return base::UTF16ToUTF8(display_name());
}

PublicAccountUser::PublicAccountUser(const AccountId& account_id)
    : DeviceLocalAccountUserBase(account_id) {}

PublicAccountUser::~PublicAccountUser() {
}

UserType PublicAccountUser::GetType() const {
  return user_manager::USER_TYPE_PUBLIC_ACCOUNT;
}

}  // namespace user_manager
