// 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 "base/prefs/pref_value_store.h"

#include "base/logging.h"
#include "base/prefs/pref_notifier.h"
#include "base/prefs/pref_observer.h"

PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
    : pref_value_store_(NULL),
      type_(PrefValueStore::INVALID_STORE) {
}

PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() {
  if (pref_store_.get()) {
    pref_store_->RemoveObserver(this);
    pref_store_ = NULL;
  }
  pref_value_store_ = NULL;
}

void PrefValueStore::PrefStoreKeeper::Initialize(
    PrefValueStore* store,
    PrefStore* pref_store,
    PrefValueStore::PrefStoreType type) {
  if (pref_store_.get()) {
    pref_store_->RemoveObserver(this);
    DCHECK(!pref_store_->HasObservers());
  }
  type_ = type;
  pref_value_store_ = store;
  pref_store_ = pref_store;
  if (pref_store_.get())
    pref_store_->AddObserver(this);
}

void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged(
    const std::string& key) {
  pref_value_store_->OnPrefValueChanged(type_, key);
}

void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted(
    bool succeeded) {
  pref_value_store_->OnInitializationCompleted(type_, succeeded);
}

PrefValueStore::PrefValueStore(PrefStore* managed_prefs,
                               PrefStore* supervised_user_prefs,
                               PrefStore* extension_prefs,
                               PrefStore* command_line_prefs,
                               PrefStore* user_prefs,
                               PrefStore* recommended_prefs,
                               PrefStore* default_prefs,
                               PrefNotifier* pref_notifier)
    : pref_notifier_(pref_notifier),
      initialization_failed_(false) {
  InitPrefStore(MANAGED_STORE, managed_prefs);
  InitPrefStore(SUPERVISED_USER_STORE, supervised_user_prefs);
  InitPrefStore(EXTENSION_STORE, extension_prefs);
  InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
  InitPrefStore(USER_STORE, user_prefs);
  InitPrefStore(RECOMMENDED_STORE, recommended_prefs);
  InitPrefStore(DEFAULT_STORE, default_prefs);

  CheckInitializationCompleted();
}

PrefValueStore::~PrefValueStore() {}

PrefValueStore* PrefValueStore::CloneAndSpecialize(
    PrefStore* managed_prefs,
    PrefStore* supervised_user_prefs,
    PrefStore* extension_prefs,
    PrefStore* command_line_prefs,
    PrefStore* user_prefs,
    PrefStore* recommended_prefs,
    PrefStore* default_prefs,
    PrefNotifier* pref_notifier) {
  DCHECK(pref_notifier);
  if (!managed_prefs)
    managed_prefs = GetPrefStore(MANAGED_STORE);
  if (!supervised_user_prefs)
    supervised_user_prefs = GetPrefStore(SUPERVISED_USER_STORE);
  if (!extension_prefs)
    extension_prefs = GetPrefStore(EXTENSION_STORE);
  if (!command_line_prefs)
    command_line_prefs = GetPrefStore(COMMAND_LINE_STORE);
  if (!user_prefs)
    user_prefs = GetPrefStore(USER_STORE);
  if (!recommended_prefs)
    recommended_prefs = GetPrefStore(RECOMMENDED_STORE);
  if (!default_prefs)
    default_prefs = GetPrefStore(DEFAULT_STORE);

  return new PrefValueStore(
      managed_prefs, supervised_user_prefs, extension_prefs, command_line_prefs,
      user_prefs, recommended_prefs, default_prefs, pref_notifier);
}

void PrefValueStore::set_callback(const PrefChangedCallback& callback) {
  pref_changed_callback_ = callback;
}

bool PrefValueStore::GetValue(const std::string& name,
                              base::Value::Type type,
                              const base::Value** out_value) const {
  // Check the |PrefStore|s in order of their priority from highest to lowest,
  // looking for the first preference value with the given |name| and |type|.
  for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
    if (GetValueFromStoreWithType(name, type, static_cast<PrefStoreType>(i),
                                  out_value))
      return true;
  }
  return false;
}

bool PrefValueStore::GetRecommendedValue(const std::string& name,
                                         base::Value::Type type,
                                         const base::Value** out_value) const {
  return GetValueFromStoreWithType(name, type, RECOMMENDED_STORE, out_value);
}

void PrefValueStore::NotifyPrefChanged(
    const std::string& path,
    PrefValueStore::PrefStoreType new_store) {
  DCHECK(new_store != INVALID_STORE);
  // A notification is sent when the pref value in any store changes. If this
  // store is currently being overridden by a higher-priority store, the
  // effective value of the pref will not have changed.
  pref_notifier_->OnPreferenceChanged(path);
  if (!pref_changed_callback_.is_null())
    pref_changed_callback_.Run(path);
}

bool PrefValueStore::PrefValueInManagedStore(const std::string& name) const {
  return PrefValueInStore(name, MANAGED_STORE);
}

bool PrefValueStore::PrefValueInExtensionStore(const std::string& name) const {
  return PrefValueInStore(name, EXTENSION_STORE);
}

bool PrefValueStore::PrefValueInUserStore(const std::string& name) const {
  return PrefValueInStore(name, USER_STORE);
}

bool PrefValueStore::PrefValueFromExtensionStore(
    const std::string& name) const {
  return ControllingPrefStoreForPref(name) == EXTENSION_STORE;
}

bool PrefValueStore::PrefValueFromUserStore(const std::string& name) const {
  return ControllingPrefStoreForPref(name) == USER_STORE;
}

bool PrefValueStore::PrefValueFromRecommendedStore(
    const std::string& name) const {
  return ControllingPrefStoreForPref(name) == RECOMMENDED_STORE;
}

bool PrefValueStore::PrefValueFromDefaultStore(const std::string& name) const {
  return ControllingPrefStoreForPref(name) == DEFAULT_STORE;
}

bool PrefValueStore::PrefValueUserModifiable(const std::string& name) const {
  PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  return effective_store >= USER_STORE ||
         effective_store == INVALID_STORE;
}

bool PrefValueStore::PrefValueExtensionModifiable(
    const std::string& name) const {
  PrefStoreType effective_store = ControllingPrefStoreForPref(name);
  return effective_store >= EXTENSION_STORE ||
         effective_store == INVALID_STORE;
}

void PrefValueStore::UpdateCommandLinePrefStore(PrefStore* command_line_prefs) {
  InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
}

bool PrefValueStore::PrefValueInStore(
    const std::string& name,
    PrefValueStore::PrefStoreType store) const {
  // Declare a temp Value* and call GetValueFromStore,
  // ignoring the output value.
  const base::Value* tmp_value = NULL;
  return GetValueFromStore(name, store, &tmp_value);
}

bool PrefValueStore::PrefValueInStoreRange(
    const std::string& name,
    PrefValueStore::PrefStoreType first_checked_store,
    PrefValueStore::PrefStoreType last_checked_store) const {
  if (first_checked_store > last_checked_store) {
    NOTREACHED();
    return false;
  }

  for (size_t i = first_checked_store;
       i <= static_cast<size_t>(last_checked_store); ++i) {
    if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
      return true;
  }
  return false;
}

PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
    const std::string& name) const {
  for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
    if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
      return static_cast<PrefStoreType>(i);
  }
  return INVALID_STORE;
}

bool PrefValueStore::GetValueFromStore(const std::string& name,
                                       PrefValueStore::PrefStoreType store_type,
                                       const base::Value** out_value) const {
  // Only return true if we find a value and it is the correct type, so stale
  // values with the incorrect type will be ignored.
  const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type));
  if (store && store->GetValue(name, out_value))
    return true;

  // No valid value found for the given preference name: set the return value
  // to false.
  *out_value = NULL;
  return false;
}

bool PrefValueStore::GetValueFromStoreWithType(
    const std::string& name,
    base::Value::Type type,
    PrefStoreType store,
    const base::Value** out_value) const {
  if (GetValueFromStore(name, store, out_value)) {
    if ((*out_value)->IsType(type))
      return true;

    LOG(WARNING) << "Expected type for " << name << " is " << type
                 << " but got " << (*out_value)->GetType()
                 << " in store " << store;
  }

  *out_value = NULL;
  return false;
}

void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type,
                                        const std::string& key) {
  NotifyPrefChanged(key, type);
}

void PrefValueStore::OnInitializationCompleted(
    PrefValueStore::PrefStoreType type, bool succeeded) {
  if (initialization_failed_)
    return;
  if (!succeeded) {
    initialization_failed_ = true;
    pref_notifier_->OnInitializationCompleted(false);
    return;
  }
  CheckInitializationCompleted();
}

void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type,
                                   PrefStore* pref_store) {
  pref_stores_[type].Initialize(this, pref_store, type);
}

void PrefValueStore::CheckInitializationCompleted() {
  if (initialization_failed_)
    return;
  for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
    scoped_refptr<PrefStore> store =
        GetPrefStore(static_cast<PrefStoreType>(i));
    if (store.get() && !store->IsInitializationComplete())
      return;
  }
  pref_notifier_->OnInitializationCompleted(true);
}
