// Copyright 2014 The Chromium OS 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 "src/commands/command_manager.h"

#include <base/values.h>
#include <weave/enum_to_string.h>
#include <weave/error.h>
#include <weave/provider/config_store.h>

#include "src/commands/schema_constants.h"
#include "src/utils.h"

namespace weave {

namespace {

const char kBaseCommandDefs[] = R"({
  "base": {
    "updateBaseConfiguration": {
      "minimalRole": "manager",
      "parameters": {
        "localDiscoveryEnabled": "boolean",
        "localAnonymousAccessMaxRole": [ "none", "viewer", "user" ],
        "localPairingEnabled": "boolean"
      },
      "results": {}
    },
    "reboot": {
      "minimalRole": "user",
      "parameters": {},
      "results": {}
    },
    "identify": {
      "minimalRole": "user",
      "parameters": {},
      "results": {}
    },
    "updateDeviceInfo": {
      "minimalRole": "manager",
      "parameters": {
        "description": "string",
        "name": "string",
        "location": "string"
      },
      "results": {}
    }
  }
})";

}  // namespace

CommandManager::CommandManager() {}

CommandManager::~CommandManager() {}

void CommandManager::AddCommandDefChanged(const base::Closure& callback) {
  on_command_changed_.push_back(callback);
  callback.Run();
}

const CommandDictionary& CommandManager::GetCommandDictionary() const {
  return dictionary_;
}

bool CommandManager::LoadBaseCommands(const base::DictionaryValue& dict,
                                      ErrorPtr* error) {
  return base_dictionary_.LoadCommands(dict, nullptr, error);
}

bool CommandManager::LoadBaseCommands(const std::string& json,
                                      ErrorPtr* error) {
  std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
  if (!dict)
    return false;
  return LoadBaseCommands(*dict, error);
}

bool CommandManager::LoadCommands(const base::DictionaryValue& dict,
                                  ErrorPtr* error) {
  bool result = dictionary_.LoadCommands(dict, &base_dictionary_, error);
  for (const auto& cb : on_command_changed_)
    cb.Run();
  return result;
}

bool CommandManager::LoadCommands(const std::string& json,
                                  ErrorPtr* error) {
  std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
  if (!dict)
    return false;
  return LoadCommands(*dict, error);
}

void CommandManager::Startup(provider::ConfigStore* config_store) {
  LOG(INFO) << "Initializing CommandManager.";

  // Load global standard GCD command dictionary.
  CHECK(LoadBaseCommands(kBaseCommandDefs, nullptr));

  // Loading the rest of commands.
  for (const auto& defs : config_store->LoadCommandDefs())
    CHECK(this->LoadCommands(defs, nullptr));
}

void CommandManager::AddCommand(
    std::unique_ptr<CommandInstance> command_instance) {
  command_queue_.Add(std::move(command_instance));
}

bool CommandManager::AddCommand(const base::DictionaryValue& command,
                                std::string* id,
                                ErrorPtr* error) {
  return AddCommand(command, UserRole::kOwner, id, error);
}

bool CommandManager::AddCommand(const base::DictionaryValue& command,
                                UserRole role,
                                std::string* id,
                                ErrorPtr* error) {
  auto command_instance = CommandInstance::FromJson(
      &command, CommandOrigin::kLocal, GetCommandDictionary(), nullptr, error);
  if (!command_instance)
    return false;

  UserRole minimal_role =
      command_instance->GetCommandDefinition()->GetMinimalRole();
  if (role < minimal_role) {
    Error::AddToPrintf(
        error, FROM_HERE, errors::commands::kDomain, "access_denied",
        "User role '%s' less than minimal: '%s'", EnumToString(role).c_str(),
        EnumToString(minimal_role).c_str());
    return false;
  }

  *id = std::to_string(++next_command_id_);
  command_instance->SetID(*id);
  AddCommand(std::move(command_instance));
  return true;
}

CommandInstance* CommandManager::FindCommand(const std::string& id) {
  return command_queue_.Find(id);
}

bool CommandManager::SetCommandVisibility(
    const std::vector<std::string>& command_names,
    CommandDefinition::Visibility visibility,
    ErrorPtr* error) {
  if (command_names.empty())
    return true;

  std::vector<CommandDefinition*> definitions;
  definitions.reserve(command_names.size());

  // Find/validate command definitions first.
  for (const std::string& name : command_names) {
    CommandDefinition* def = dictionary_.FindCommand(name);
    if (!def) {
      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                         errors::commands::kInvalidCommandName,
                         "Command '%s' is unknown", name.c_str());
      return false;
    }
    definitions.push_back(def);
  }

  // Now that we know that all the command names were valid,
  // update the respective commands' visibility.
  for (CommandDefinition* def : definitions)
    def->SetVisibility(visibility);
  for (const auto& cb : on_command_changed_)
    cb.Run();
  return true;
}

void CommandManager::AddCommandAddedCallback(
    const Device::CommandCallback& callback) {
  command_queue_.AddCommandAddedCallback(callback);
}

void CommandManager::AddCommandRemovedCallback(
    const Device::CommandCallback& callback) {
  command_queue_.AddCommandRemovedCallback(callback);
}

}  // namespace weave
