// Copyright 2015 The Cobalt Authors. 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
