// 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/console_commands.h"

#include "base/logging.h"

namespace base {

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

#if defined(ENABLE_DEBUG_CONSOLE)

ConsoleCommandManager::CommandHandler::CommandHandler(
    const std::string& command,
    const ConsoleCommandManager::CommandCallback& callback,
    const std::string& short_help, const std::string& long_help)
    : command_(command),
      callback_(callback),
      short_help_(short_help),
      long_help_(long_help) {
  ConsoleCommandManager* manager = ConsoleCommandManager::GetInstance();
  DCHECK(manager);
  manager->RegisterCommandHandler(this);
}

ConsoleCommandManager::CommandHandler::~CommandHandler() {
  ConsoleCommandManager* manager = ConsoleCommandManager::GetInstance();
  DCHECK(manager);
  manager->UnregisterCommandHandler(this);
}

void ConsoleCommandManager::HandleCommand(const std::string& command,
                                          const std::string& message) const {
  DCHECK_GT(command.length(), size_t(0));
  base::AutoLock auto_lock(lock_);
  CommandHandlerMap::const_iterator iter = command_command_map_.find(command);
  if (iter != command_command_map_.end()) {
    iter->second->callback().Run(message);
  } else {
    DLOG(WARNING) << "No handler registered for command: " << command;
  }
}

std::set<std::string> ConsoleCommandManager::GetRegisteredCommands() const {
  std::set<std::string> result;
  base::AutoLock auto_lock(lock_);
  for (CommandHandlerMap::const_iterator iter = command_command_map_.begin();
       iter != command_command_map_.end(); ++iter) {
    result.insert(iter->first);
  }
  return result;
}

std::string ConsoleCommandManager::GetShortHelp(
    const std::string& command) const {
  base::AutoLock auto_lock(lock_);
  CommandHandlerMap::const_iterator iter = command_command_map_.find(command);
  if (iter != command_command_map_.end()) {
    return iter->second->short_help();
  }
  return "No help available for unregistered command: " + command;
}

std::string ConsoleCommandManager::GetLongHelp(
    const std::string& command) const {
  base::AutoLock auto_lock(lock_);
  CommandHandlerMap::const_iterator iter = command_command_map_.find(command);
  if (iter != command_command_map_.end()) {
    return iter->second->long_help();
  }
  return "No help available for unregistered command: " + command;
}

void ConsoleCommandManager::RegisterCommandHandler(
    const CommandHandler* handler) {
  DCHECK_GT(handler->command().length(), size_t(0));
  base::AutoLock auto_lock(lock_);
  command_command_map_[handler->command()] = handler;
}

void ConsoleCommandManager::UnregisterCommandHandler(
    const CommandHandler* handler) {
  DCHECK_GT(handler->command().length(), size_t(0));
  base::AutoLock auto_lock(lock_);
  command_command_map_.erase(handler->command());
}

#else   // ENABLE_DEBUG_CONSOLE

ConsoleCommandManager::CommandHandler::CommandHandler(
    const std::string& command,
    const ConsoleCommandManager::CommandCallback& callback,
    const std::string& short_help, const std::string& long_help) {
  UNREFERENCED_PARAMETER(command);
  UNREFERENCED_PARAMETER(callback);
  UNREFERENCED_PARAMETER(short_help);
  UNREFERENCED_PARAMETER(long_help);
}

ConsoleCommandManager::CommandHandler::~CommandHandler() {}

void ConsoleCommandManager::HandleCommand(const std::string& command,
                                          const std::string& message) const {
  UNREFERENCED_PARAMETER(command);
  UNREFERENCED_PARAMETER(message);
}

std::set<std::string> ConsoleCommandManager::GetRegisteredCommands() const {
  return std::set<std::string>();
}

std::string ConsoleCommandManager::GetShortHelp(
    const std::string& command) const {
  UNREFERENCED_PARAMETER(command);
  return "";
}

std::string ConsoleCommandManager::GetLongHelp(
    const std::string& command) const {
  UNREFERENCED_PARAMETER(command);
  return "";
}
#endif  // ENABLE_DEBUG_CONSOLE

}  // namespace base
