// Copyright 2015 The Weave 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_dictionary.h"

#include <base/values.h>
#include <weave/enum_to_string.h>

#include "src/commands/command_definition.h"
#include "src/commands/schema_constants.h"
#include "src/string_utils.h"

namespace weave {

bool CommandDictionary::LoadCommands(const base::DictionaryValue& json,
                                     const CommandDictionary* base_commands,
                                     ErrorPtr* error) {
  CommandMap new_defs;

  // |json| contains a list of nested objects with the following structure:
  // {"<pkg_name>": {"<cmd_name>": {"parameters": {object_schema}}, ...}, ...}
  // Iterate over packages
  base::DictionaryValue::Iterator package_iter(json);
  while (!package_iter.IsAtEnd()) {
    std::string package_name = package_iter.key();
    const base::DictionaryValue* package_value = nullptr;
    if (!package_iter.value().GetAsDictionary(&package_value)) {
      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                         errors::commands::kTypeMismatch,
                         "Expecting an object for package '%s'",
                         package_name.c_str());
      return false;
    }
    // Iterate over command definitions within the current package.
    base::DictionaryValue::Iterator command_iter(*package_value);
    while (!command_iter.IsAtEnd()) {
      std::string command_name = command_iter.key();
      if (command_name.empty()) {
        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                           errors::commands::kInvalidCommandName,
                           "Unnamed command encountered in package '%s'",
                           package_name.c_str());
        return false;
      }
      const base::DictionaryValue* command_def_json = nullptr;
      if (!command_iter.value().GetAsDictionary(&command_def_json)) {
        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                           errors::commands::kTypeMismatch,
                           "Expecting an object for command '%s'",
                           command_name.c_str());
        return false;
      }
      // Construct the compound command name as "pkg_name.cmd_name".
      std::string full_command_name = Join(".", package_name, command_name);

      const ObjectSchema* base_parameters_def = nullptr;
      const ObjectSchema* base_progress_def = nullptr;
      const ObjectSchema* base_results_def = nullptr;
      // By default make it available to all clients.
      auto visibility = CommandDefinition::Visibility::GetAll();
      UserRole minimal_role{UserRole::kUser};
      if (base_commands) {
        auto cmd = base_commands->FindCommand(full_command_name);
        if (cmd) {
          base_parameters_def = cmd->GetParameters();
          base_progress_def = cmd->GetProgress();
          base_results_def = cmd->GetResults();
          visibility = cmd->GetVisibility();
          minimal_role = cmd->GetMinimalRole();
        }

        // If the base command dictionary was provided but the command was not
        // found in it, this must be a custom (vendor) command. GCD spec states
        // that all custom command names must begin with "_". Let's enforce
        // this rule here.
        if (!cmd) {
          if (command_name.front() != '_') {
            Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                               errors::commands::kInvalidCommandName,
                               "The name of custom command '%s' in package '%s'"
                               " must start with '_'",
                               command_name.c_str(), package_name.c_str());
            return false;
          }
        }
      }

      auto parameters_schema = BuildObjectSchema(
          command_def_json, commands::attributes::kCommand_Parameters,
          base_parameters_def, full_command_name, error);
      if (!parameters_schema)
        return false;

      auto progress_schema = BuildObjectSchema(
          command_def_json, commands::attributes::kCommand_Progress,
          base_progress_def, full_command_name, error);
      if (!progress_schema)
        return false;

      auto results_schema = BuildObjectSchema(
          command_def_json, commands::attributes::kCommand_Results,
          base_results_def, full_command_name, error);
      if (!results_schema)
        return false;

      std::string value;
      if (command_def_json->GetString(commands::attributes::kCommand_Visibility,
                                      &value)) {
        if (!visibility.FromString(value, error)) {
          Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                             errors::commands::kInvalidCommandVisibility,
                             "Error parsing command '%s'",
                             full_command_name.c_str());
          return false;
        }
      }

      if (command_def_json->GetString(commands::attributes::kCommand_Role,
                                      &value)) {
        if (!StringToEnum(value, &minimal_role)) {
          Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                             errors::commands::kInvalidPropValue,
                             "Invalid role: '%s'", value.c_str());
          Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                             errors::commands::kInvalidMinimalRole,
                             "Error parsing command '%s'",
                             full_command_name.c_str());
          return false;
        }
      }

      std::unique_ptr<CommandDefinition> command_def{new CommandDefinition{
          std::move(parameters_schema), std::move(progress_schema),
          std::move(results_schema)}};
      command_def->SetVisibility(visibility);
      command_def->SetMinimalRole(minimal_role);
      new_defs.emplace(full_command_name, std::move(command_def));

      command_iter.Advance();
    }
    package_iter.Advance();
  }

  // Verify that newly loaded command definitions do not override existing
  // definitions in another category. This is unlikely, but we don't want to let
  // one vendor daemon to define the same commands already handled by another
  // daemon on the same device.
  for (const auto& pair : new_defs) {
    auto iter = definitions_.find(pair.first);
    CHECK(iter == definitions_.end()) << "Definition for command '"
                                      << pair.first
                                      << "' overrides an earlier definition";
  }

  // Insert new definitions into the global map.
  for (auto& pair : new_defs)
    definitions_.emplace(pair.first, std::move(pair.second));
  return true;
}

std::unique_ptr<ObjectSchema> CommandDictionary::BuildObjectSchema(
    const base::DictionaryValue* command_def_json,
    const char* property_name,
    const ObjectSchema* base_def,
    const std::string& command_name,
    ErrorPtr* error) {
  auto object_schema = ObjectSchema::Create();

  const base::DictionaryValue* schema_def = nullptr;
  if (!command_def_json->GetDictionaryWithoutPathExpansion(property_name,
                                                           &schema_def)) {
    if (base_def)
      return base_def->Clone();
    return object_schema;
  }

  if (!object_schema->FromJson(schema_def, base_def, error)) {
    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                       errors::commands::kInvalidObjectSchema,
                       "Invalid definition for command '%s'",
                       command_name.c_str());
    return {};
  }

  return object_schema;
}

std::unique_ptr<base::DictionaryValue> CommandDictionary::GetCommandsAsJson(
    const std::function<bool(const CommandDefinition*)>& filter,
    bool full_schema,
    ErrorPtr* error) const {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  for (const auto& pair : definitions_) {
    // Check if the command definition has the desired visibility.
    // If not, then skip it.
    if (!filter(pair.second.get()))
      continue;

    std::unique_ptr<base::DictionaryValue> parameters =
        pair.second->GetParameters()->ToJson(full_schema, true);
    CHECK(parameters);
    // Progress and results are not part of public commandDefs.

    auto parts = SplitAtFirst(pair.first, ".", true);
    const std::string& package_name = parts.first;
    const std::string& command_name = parts.second;

    base::DictionaryValue* package = nullptr;
    if (!dict->GetDictionaryWithoutPathExpansion(package_name, &package)) {
      // If this is the first time we encounter this package, create a JSON
      // object for it.
      package = new base::DictionaryValue;
      dict->SetWithoutPathExpansion(package_name, package);
    }
    base::DictionaryValue* command_def = new base::DictionaryValue;
    command_def->Set(commands::attributes::kCommand_Parameters,
                     parameters.release());
    command_def->SetString(commands::attributes::kCommand_Role,
                           EnumToString(pair.second->GetMinimalRole()));
    package->SetWithoutPathExpansion(command_name, command_def);
  }
  return dict;
}

const CommandDefinition* CommandDictionary::FindCommand(
    const std::string& command_name) const {
  auto pair = definitions_.find(command_name);
  return (pair != definitions_.end()) ? pair->second.get() : nullptr;
}

CommandDefinition* CommandDictionary::FindCommand(
    const std::string& command_name) {
  auto pair = definitions_.find(command_name);
  return (pair != definitions_.end()) ? pair->second.get() : nullptr;
}

void CommandDictionary::Clear() {
  definitions_.clear();
}

}  // namespace weave
