// Copyright 2016 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/access_api_handler.h"

#include <gtest/gtest.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>

#include "src/component_manager_impl.h"
#include "src/access_black_list_manager.h"
#include "src/data_encoding.h"

using testing::_;
using testing::AnyOf;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;
using testing::WithArgs;

namespace weave {

class MockAccessBlackListManager : public AccessBlackListManager {
 public:
  MOCK_METHOD4(Block,
               void(const std::vector<uint8_t>&,
                    const std::vector<uint8_t>&,
                    const base::Time&,
                    const DoneCallback&));
  MOCK_METHOD3(Unblock,
               bool(const std::vector<uint8_t>&,
                    const std::vector<uint8_t>&,
                    ErrorPtr*));
  MOCK_CONST_METHOD0(GetEntries, std::vector<Entry>());
  MOCK_CONST_METHOD0(GetSize, size_t());
  MOCK_CONST_METHOD0(GetCapacity, size_t());
};

class AccessApiHandlerTest : 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("_accessControlBlackList.block",
                                           "_accessControlBlackList.unblock",
                                           "_accessControlBlackList.list"),
                                  _))
        .WillRepeatedly(
            Invoke(&component_manager_, &ComponentManager::AddCommandHandler));

    EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(0));

    EXPECT_CALL(access_manager_, GetCapacity()).WillRepeatedly(Return(10));

    handler_.reset(new AccessApiHandler{&device_, &access_manager_});
  }

  const base::DictionaryValue& 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);
    EXPECT_NE(nullptr, command_instance.get());
    component_manager_.AddCommand(std::move(command_instance));
    EXPECT_EQ(Command::State::kDone,
              component_manager_.FindCommand(id)->GetState());
    return component_manager_.FindCommand(id)->GetResults();
  }

  std::unique_ptr<base::DictionaryValue> GetState() {
    std::string path =
        component_manager_.FindComponentWithTrait("_accessControlBlackList");
    EXPECT_FALSE(path.empty());
    const auto* component = component_manager_.FindComponent(path, nullptr);
    EXPECT_TRUE(component);
    const base::DictionaryValue* state = nullptr;
    EXPECT_TRUE(
        component->GetDictionary("state._accessControlBlackList", &state));
    return std::unique_ptr<base::DictionaryValue>{state->DeepCopy()};
  }

  ComponentManagerImpl component_manager_;
  StrictMock<test::MockDevice> device_;
  StrictMock<MockAccessBlackListManager> access_manager_;
  std::unique_ptr<AccessApiHandler> handler_;
};

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

  auto expected = R"({
    "commands": {
      "block": {
        "minimalRole": "owner",
        "parameters": {
          "userId": {
            "type": "string"
          },
          "applicationId": {
            "type": "string"
          },
          "expirationTimeoutSec": {
            "type": "integer"
          }
        }
      },
      "unblock": {
        "minimalRole": "owner",
        "parameters": {
          "userId": {
            "type": "string"
          },
          "applicationId": {
            "type": "string"
          }
        }
      },
      "list": {
        "minimalRole": "owner",
        "parameters": {},
        "results": {
          "blackList": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "string"
                },
                "applicationId": {
                  "type": "string"
                }
              },
              "additionalProperties": false
            }
          }
        }
      }
    },
    "state": {
      "size": {
        "type": "integer",
        "isRequired": true
      },
      "capacity": {
        "type": "integer",
        "isRequired": true
      }
    }
  })";
  EXPECT_JSON_EQ(expected, *trait);

  EXPECT_JSON_EQ((R"({
    "capacity": 10,
    "size": 0
  })"),
                 *GetState());
}

TEST_F(AccessApiHandlerTest, Block) {
  EXPECT_CALL(access_manager_, Block(std::vector<uint8_t>{1, 2, 3},
                                     std::vector<uint8_t>{3, 4, 5}, _, _))
      .WillOnce(WithArgs<3>(
          Invoke([](const DoneCallback& callback) { callback.Run(nullptr); })));
  EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(1));

  AddCommand(R"({
    'name' : '_accessControlBlackList.block',
    'component': 'accessControl',
    'parameters': {
      'userId': 'AQID',
      'applicationId': 'AwQF',
      'expirationTimeoutSec': 1234
    }
  })");
  EXPECT_JSON_EQ((R"({
    "capacity": 10,
    "size": 1
  })"),
                 *GetState());
}

TEST_F(AccessApiHandlerTest, Unblock) {
  EXPECT_CALL(access_manager_, Unblock(std::vector<uint8_t>{1, 2, 3},
                                       std::vector<uint8_t>{3, 4, 5}, _))
      .WillOnce(Return(true));
  EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(4));

  AddCommand(R"({
    'name' : '_accessControlBlackList.unblock',
    'component': 'accessControl',
    'parameters': {
      'userId': 'AQID',
      'applicationId': 'AwQF',
      'expirationTimeoutSec': 1234
    }
  })");
  EXPECT_JSON_EQ((R"({
    "capacity": 10,
    "size": 4
  })"),
                 *GetState());
}

TEST_F(AccessApiHandlerTest, List) {
  std::vector<AccessBlackListManager::Entry> entries{
      {{11, 12, 13}, {21, 22, 23}, base::Time::FromTimeT(1410000000)},
      {{31, 32, 33}, {41, 42, 43}, base::Time::FromTimeT(1420000000)},
  };
  EXPECT_CALL(access_manager_, GetEntries()).WillOnce(Return(entries));
  EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(4));

  auto expected = R"({
    "blackList": [ {
      "applicationId": "FRYX",
      "userId": "CwwN"
    }, {
       "applicationId": "KSor",
       "userId": "HyAh"
    } ]
  })";

  EXPECT_JSON_EQ(expected, AddCommand(R"({
    'name' : '_accessControlBlackList.list',
    'component': 'accessControl',
    'parameters': {
    }
  })"));
}
}  // namespace weave
