// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/base/c_val.h"

#include <sstream>

namespace base {

CValManager* CValManager::GetInstance() {
  return Singleton<CValManager,
                   StaticMemorySingletonTraits<CValManager> >::get();
}

CValManager::CValManager() : value_lock_refptr_(new RefCountedThreadSafeLock) {
  // Allocate these dynamically since CValManager may live across DLL boundaries
  // and so this allows its size to be more consistent (and avoids compiler
  // warnings on some platforms).
  registered_vars_ = new NameVarMap();
#if defined(ENABLE_DEBUG_C_VAL)
  on_changed_hook_set_ = new base::hash_set<OnChangedHook*>();
#endif  // ENABLE_DEBUG_C_VAL
}

CValManager::~CValManager() {
  // Lock the value lock prior to notifying the surviving CVals that the manager
  // has been destroyed. This ensures that they will not attempt to make calls
  // into the manager during destruction.
  base::AutoLock auto_lock(value_lock_refptr_->GetLock());
  for (NameVarMap::iterator iter = registered_vars_->begin();
       iter != registered_vars_->end(); ++iter) {
    iter->second->OnManagerDestroyed();
  }

#if defined(ENABLE_DEBUG_C_VAL)
  delete on_changed_hook_set_;
#endif  // ENABLE_DEBUG_C_VAL
  delete registered_vars_;
}

void CValManager::RegisterCVal(
    const CValDetail::CValBase* cval,
    scoped_refptr<base::RefCountedThreadSafeLock>* value_lock) {
  base::AutoLock auto_lock(cvals_lock_);

  // CVals cannot share name.  If this assert is triggered, we are trying to
  // register more than one CVal with the same name, which this system is
  // not designed to handle.
  DCHECK(registered_vars_->find(cval->GetName()) == registered_vars_->end());

  (*registered_vars_)[cval->GetName()] = cval;
  *value_lock = value_lock_refptr_;
}

void CValManager::UnregisterCVal(const CValDetail::CValBase* cval) {
  base::AutoLock auto_lock(cvals_lock_);

  NameVarMap::iterator found = registered_vars_->find(cval->GetName());
  DCHECK(found != registered_vars_->end());
  if (found != registered_vars_->end()) {
    registered_vars_->erase(found);
  }
}

#if defined(ENABLE_DEBUG_C_VAL)
void CValManager::PushValueChangedEvent(const CValDetail::CValBase* cval,
                                        const CValGenericValue& value) {
  base::AutoLock auto_lock(hooks_lock_);

  // Iterate through the hooks sending each of them the value changed event.
  for (OnChangeHookSet::iterator iter = on_changed_hook_set_->begin();
       iter != on_changed_hook_set_->end(); ++iter) {
    (*iter)->OnValueChanged(cval->GetName(), value);
  }
}

CValManager::OnChangedHook::OnChangedHook() {
  CValManager* cvm = CValManager::GetInstance();
  base::AutoLock auto_lock(cvm->hooks_lock_);

  // Register this hook with the CValManager
  bool was_inserted ALLOW_UNUSED =
      cvm->on_changed_hook_set_->insert(this).second;
  DCHECK(was_inserted);
}

CValManager::OnChangedHook::~OnChangedHook() {
  CValManager* cvm = CValManager::GetInstance();
  base::AutoLock auto_lock(cvm->hooks_lock_);

  // Deregister this hook with the CValManager
  size_t values_erased ALLOW_UNUSED = cvm->on_changed_hook_set_->erase(this);
  DCHECK_EQ(values_erased, 1);
}
#endif  // ENABLE_DEBUG_C_VAL

std::set<std::string> CValManager::GetOrderedCValNames() {
  std::set<std::string> ret;
  base::AutoLock auto_lock(cvals_lock_);

  // Return all registered CVal names, as an std::set to show they are sorted.
  for (NameVarMap::const_iterator iter = registered_vars_->begin();
       iter != registered_vars_->end(); ++iter) {
    ret.insert(iter->first);
  }

  return ret;
}

optional<std::string> CValManager::GetCValStringValue(const std::string& name,
                                                      bool pretty) {
  base::AutoLock auto_lock(cvals_lock_);

  // Return the value of a CVal, if it exists.  If it does not exist,
  // indicate that it does not exist.
  NameVarMap::const_iterator found = registered_vars_->find(name);
  if (found == registered_vars_->end()) {
    return nullopt;
  } else {
    return (pretty ? found->second->GetValueAsPrettyString()
                   : found->second->GetValueAsString());
  }
}

optional<std::string> CValManager::GetValueAsString(const std::string& name) {
  return GetCValStringValue(name, false);
}

optional<std::string> CValManager::GetValueAsPrettyString(
    const std::string& name) {
  return GetCValStringValue(name, true);
}

}  // namespace base
