// 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/strings/string_number_conversions.h>
#include <base/values.h>
#include <gtest/gtest.h>
#include <weave/provider/test/mock_config_store.h>
#include <weave/provider/test/mock_http_client.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>

#include "src/component_manager_impl.h"
#include "src/config.h"
#include "src/device_registration_info.h"

using testing::_;
using testing::AnyOf;
using testing::Eq;
using testing::Invoke;
using testing::Return;
using testing::ReturnRef;
using testing::StrictMock;

namespace weave {

class BaseApiHandlerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    EXPECT_CALL(device_, AddTraitDefinitionsFromJson(_))
        .WillRepeatedly(Invoke([this](const std::string& json) {
          EXPECT_TRUE(component_manager_.LoadTraits(json, nullptr));
        }));
    EXPECT_CALL(device_, SetStateProperties(_, _, _))
        .WillRepeatedly(Invoke(&component_manager_,
                               &ComponentManager::SetStateProperties));
    EXPECT_CALL(device_, SetStateProperty(_, _, _, _))
        .WillRepeatedly(Invoke(&component_manager_,
                               &ComponentManager::SetStateProperty));
    EXPECT_CALL(device_, AddComponent(_, _, _))
        .WillRepeatedly(Invoke([this](const std::string& name,
                                      const std::vector<std::string>& traits,
                                      ErrorPtr* error) {
          return component_manager_.AddComponent("", name, traits, error);
        }));

    EXPECT_CALL(device_, AddCommandHandler(_,
                                           AnyOf("base.updateBaseConfiguration",
                                                 "base.updateDeviceInfo"),
                                           _))
        .WillRepeatedly(Invoke(&component_manager_,
                               &ComponentManager::AddCommandHandler));

    std::unique_ptr<Config> config{new Config{&config_store_}};
    config->Load();
    dev_reg_.reset(new DeviceRegistrationInfo(&component_manager_,
                                              std::move(config), nullptr,
                                              &http_client_, nullptr));

    EXPECT_CALL(device_, GetSettings())
        .WillRepeatedly(ReturnRef(dev_reg_->GetSettings()));

    handler_.reset(new BaseApiHandler{dev_reg_.get(), &device_});
  }

  void AddCommand(const std::string& command) {
    std::string id;
    auto command_instance = component_manager_.ParseCommandInstance(
        *test::CreateDictionaryValue(command.c_str()), Command::Origin::kLocal,
        UserRole::kOwner, &id, nullptr);
    ASSERT_NE(nullptr, command_instance.get());
    component_manager_.AddCommand(std::move(command_instance));
    EXPECT_EQ(Command::State::kDone,
              component_manager_.FindCommand(id)->GetState());
  }

  std::unique_ptr<base::DictionaryValue> GetBaseState() {
    std::unique_ptr<base::DictionaryValue> state;
    std::string path = component_manager_.FindComponentWithTrait("base");
    EXPECT_FALSE(path.empty());
    const auto* component = component_manager_.FindComponent(path, nullptr);
    CHECK(component);
    const base::DictionaryValue* base_state = nullptr;
    if (component->GetDictionary("state.base", &base_state))
      state.reset(base_state->DeepCopy());
    else
      state.reset(new base::DictionaryValue);
    return state;
  }

  provider::test::MockConfigStore config_store_;
  StrictMock<provider::test::MockHttpClient> http_client_;
  std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
  ComponentManagerImpl component_manager_;
  std::unique_ptr<BaseApiHandler> handler_;
  StrictMock<test::MockDevice> device_;
};

TEST_F(BaseApiHandlerTest, Initialization) {
  const base::DictionaryValue* trait = nullptr;
  ASSERT_TRUE(component_manager_.GetTraits().GetDictionary("base", &trait));

  auto expected = R"({
    "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",
      "localAnonymousAccessMaxRole": [ "none", "viewer", "user" ],
      "localDiscoveryEnabled": "boolean",
      "localPairingEnabled": "boolean"
   }
  })";
  EXPECT_JSON_EQ(expected, *trait);
}

TEST_F(BaseApiHandlerTest, UpdateBaseConfiguration) {
  const Settings& settings = dev_reg_->GetSettings();

  AddCommand(R"({
    'name' : 'base.updateBaseConfiguration',
    'component': 'weave',
    'parameters': {
      'localDiscoveryEnabled': false,
      'localAnonymousAccessMaxRole': 'none',
      'localPairingEnabled': false
    }
  })");
  EXPECT_EQ(AuthScope::kNone, settings.local_anonymous_access_role);
  EXPECT_FALSE(settings.local_discovery_enabled);
  EXPECT_FALSE(settings.local_pairing_enabled);

  auto expected = R"({
    'firmwareVersion': 'TEST_FIRMWARE',
    'localAnonymousAccessMaxRole': 'none',
    'localDiscoveryEnabled': false,
    'localPairingEnabled': false
  })";
  EXPECT_JSON_EQ(expected, *GetBaseState());

  AddCommand(R"({
    'name' : 'base.updateBaseConfiguration',
    'component': 'weave',
    'parameters': {
      'localDiscoveryEnabled': true,
      'localAnonymousAccessMaxRole': 'user',
      'localPairingEnabled': true
    }
  })");
  EXPECT_EQ(AuthScope::kUser, settings.local_anonymous_access_role);
  EXPECT_TRUE(settings.local_discovery_enabled);
  EXPECT_TRUE(settings.local_pairing_enabled);
  expected = R"({
    'firmwareVersion': 'TEST_FIRMWARE',
    'localAnonymousAccessMaxRole': 'user',
    'localDiscoveryEnabled': true,
    'localPairingEnabled': true
  })";
  EXPECT_JSON_EQ(expected, *GetBaseState());

  {
    Config::Transaction change{dev_reg_->GetMutableConfig()};
    change.set_local_anonymous_access_role(AuthScope::kViewer);
  }
  expected = R"({
    'firmwareVersion': 'TEST_FIRMWARE',
    'localAnonymousAccessMaxRole': 'viewer',
    'localDiscoveryEnabled': true,
    'localPairingEnabled': true
  })";
  EXPECT_JSON_EQ(expected, *GetBaseState());
}

TEST_F(BaseApiHandlerTest, UpdateDeviceInfo) {
  AddCommand(R"({
    'name' : 'base.updateDeviceInfo',
    'component': 'weave',
    'parameters': {
      'name': 'testName',
      'description': 'testDescription',
      'location': 'testLocation'
    }
  })");

  const Settings& config = dev_reg_->GetSettings();
  EXPECT_EQ("testName", config.name);
  EXPECT_EQ("testDescription", config.description);
  EXPECT_EQ("testLocation", config.location);

  AddCommand(R"({
    'name' : 'base.updateDeviceInfo',
    'component': 'weave',
    'parameters': {
      'location': 'newLocation'
    }
  })");

  EXPECT_EQ("testName", config.name);
  EXPECT_EQ("testDescription", config.description);
  EXPECT_EQ("newLocation", config.location);
}

}  // namespace weave
