// 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[] = "base";
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"
            }
          }
        },
        "reboot": {
          "minimalRole": "user",
          "parameters": {},
          "errors": ["notEnoughBattery"]
        },
        "identify": {
          "minimalRole": "user",
          "parameters": {}
        }
      },
      "state": {
        "firmwareVersion": {
          "type": "string",
          "isRequired": true
        },
        "localDiscoveryEnabled": {
          "type": "boolean",
          "isRequired": true
        },
        "localAnonymousAccessMaxRole": {
          "type": "string",
          "enum": [ "none", "viewer", "user" ],
        "isRequired": true
        },
        "localPairingEnabled": {
          "type": "boolean",
          "isRequired": true
        },
        "connectionStatus": {
          "type": "string"
        },
        "network": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "name": { "type": "string" }
          }
        }
      }
    }
  })");
  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
