// 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/time/default_clock.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));

    config_.Load();
    dev_reg_.reset(new DeviceRegistrationInfo(&config_, &component_manager_,
                                              nullptr, &http_client_, nullptr,
                                              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_;
  Config config_{&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"
          }
        }
      },
      "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" }
        }
      }
    }
  })";
  EXPECT_JSON_EQ(expected, *trait);
}

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

  AddCommand(R"({
    'name' : 'base.updateBaseConfiguration',
    'component': 'base',
    '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': 'base',
    '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': 'base',
    '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': 'base',
    'parameters': {
      'location': 'newLocation'
    }
  })");

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

}  // namespace weave
