// 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_;
}

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;
}

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;
}

}  // namespace user_manager
