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

#include <base/bind.h>
#include <weave/device.h>

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

namespace weave {

namespace {
const char kBaseComponent[] = "weave";
const char kBaseTrait[] = "base";
const char kBaseStateFirmwareVersion[] = "base.firmwareVersion";
const char kBaseStateAnonymousAccessRole[] = "base.localAnonymousAccessMaxRole";
const char kBaseStateDiscoveryEnabled[] = "base.localDiscoveryEnabled";
const char kBaseStatePairingEnabled[] = "base.localPairingEnabled";
}  // namespace

BaseApiHandler::BaseApiHandler(DeviceRegistrationInfo* device_info,
                               Device* device)
    : device_info_{device_info}, device_{device} {
  device_->AddTraitDefinitionsFromJson(R"({
    "base": {
      "commands": {
        "updateBaseConfiguration": {
          "minimalRole": "manager",
          "parameters": {
            "localAnonymousAccessMaxRole": {
              "enum": [ "none", "viewer", "user" ],
              "type": "string"
            },
            "localDiscoveryEnabled": {
              "type": "boolean"
            },
            "localPairingEnabled": {
              "type": "boolean"
            }
          }
        },
        "updateDeviceInfo": {
          "minimalRole": "manager",
          "parameters": {
            "description": {
              "type": "string"
            },
            "location": {
              "type": "string"
            },
            "name": {
              "type": "string"
            }
          }
        }
      },
      "state": {
        "firmwareVersion": "string",
        "localDiscoveryEnabled": "boolean",
        "localAnonymousAccessMaxRole": [ "none", "viewer", "user" ],
        "localPairingEnabled": "boolean"
      }
    }
  })");
  CHECK(device_->AddComponent(kBaseComponent, {kBaseTrait}, nullptr));
  OnConfigChanged(device_->GetSettings());

  const auto& settings = device_info_->GetSettings();
  base::DictionaryValue state;
  state.SetString(kBaseStateFirmwareVersion, settings.firmware_version);
  CHECK(device_->SetStateProperty(kBaseComponent, kBaseStateFirmwareVersion,
                                  base::StringValue{settings.firmware_version},
                                  nullptr));

  device_->AddCommandHandler(
      kBaseComponent, "base.updateBaseConfiguration",
      base::Bind(&BaseApiHandler::UpdateBaseConfiguration,
                 weak_ptr_factory_.GetWeakPtr()));

  device_->AddCommandHandler(kBaseComponent, "base.updateDeviceInfo",
                             base::Bind(&BaseApiHandler::UpdateDeviceInfo,
                                        weak_ptr_factory_.GetWeakPtr()));

  device_info_->GetMutableConfig()->AddOnChangedCallback(base::Bind(
      &BaseApiHandler::OnConfigChanged, weak_ptr_factory_.GetWeakPtr()));
}

void BaseApiHandler::UpdateBaseConfiguration(
    const std::weak_ptr<Command>& cmd) {
  auto command = cmd.lock();
  if (!command)
    return;
  CHECK(command->GetState() == Command::State::kQueued)
      << EnumToString(command->GetState());
  command->SetProgress(base::DictionaryValue{}, nullptr);

  const auto& settings = device_info_->GetSettings();
  std::string anonymous_access_role{
      EnumToString(settings.local_anonymous_access_role)};
  bool discovery_enabled{settings.local_discovery_enabled};
  bool pairing_enabled{settings.local_pairing_enabled};

  const auto& parameters = command->GetParameters();
  parameters.GetString("localAnonymousAccessMaxRole", &anonymous_access_role);
  parameters.GetBoolean("localDiscoveryEnabled", &discovery_enabled);
  parameters.GetBoolean("localPairingEnabled", &pairing_enabled);

  AuthScope auth_scope{AuthScope::kNone};
  if (!StringToEnum(anonymous_access_role, &auth_scope)) {
    ErrorPtr error;
    Error::AddToPrintf(&error, FROM_HERE, errors::commands::kDomain,
                       errors::commands::kInvalidPropValue,
                       "Invalid localAnonymousAccessMaxRole value '%s'",
                       anonymous_access_role.c_str());
    command->Abort(error.get(), nullptr);
    return;
  }

  device_info_->UpdateBaseConfig(auth_scope, discovery_enabled,
                                 pairing_enabled);

  command->Complete({}, nullptr);
}

void BaseApiHandler::OnConfigChanged(const Settings& settings) {
  base::DictionaryValue state;
  state.SetString(kBaseStateAnonymousAccessRole,
                  EnumToString(settings.local_anonymous_access_role));
  state.SetBoolean(kBaseStateDiscoveryEnabled,
                   settings.local_discovery_enabled);
  state.SetBoolean(kBaseStatePairingEnabled, settings.local_pairing_enabled);
  device_->SetStateProperties(kBaseComponent, state, nullptr);
}

void BaseApiHandler::UpdateDeviceInfo(const std::weak_ptr<Command>& cmd) {
  auto command = cmd.lock();
  if (!command)
    return;
  CHECK(command->GetState() == Command::State::kQueued)
      << EnumToString(command->GetState());
  command->SetProgress(base::DictionaryValue{}, nullptr);

  const auto& settings = device_info_->GetSettings();
  std::string name{settings.name};
  std::string description{settings.description};
  std::string location{settings.location};

  const auto& parameters = command->GetParameters();
  parameters.GetString("name", &name);
  parameters.GetString("description", &description);
  parameters.GetString("location", &location);

  device_info_->UpdateDeviceInfo(name, description, location);
  command->Complete({}, nullptr);
}

}  // namespace weave
