// 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/provider/test/fake_task_runner.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>

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

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

namespace weave {

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("_accessRevocationList.revoke",
                                           "_accessRevocationList.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("_accessRevocationList");
    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._accessRevocationList", &state));
    return std::unique_ptr<base::DictionaryValue>{state->DeepCopy()};
  }

  StrictMock<provider::test::FakeTaskRunner> task_runner_;
  ComponentManagerImpl component_manager_{&task_runner_};
  StrictMock<test::MockDevice> device_;
  StrictMock<test::MockAccessBlackListManager> access_manager_;
  std::unique_ptr<AccessApiHandler> handler_;
};

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

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

  expected = R"({
    "capacity": 10
  })";
  EXPECT_JSON_EQ(expected, *GetState());
}

TEST_F(AccessApiHandlerTest, Revoke) {
  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' : '_accessRevocationList.revoke',
    'component': 'accessControl',
    'parameters': {
      'userId': 'AQID',
      'applicationId': 'AwQF',
      'expirationTime': 1234
    }
  })");

  auto expected = R"({
    "capacity": 10
  })";
  EXPECT_JSON_EQ(expected, *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"({
    "revocationListEntries": [ {
      "applicationId": "FRYX",
      "userId": "CwwN"
    }, {
       "applicationId": "KSor",
       "userId": "HyAh"
    } ]
  })";

  const auto& results = AddCommand(R"({
    'name' : '_accessRevocationList.list',
    'component': 'accessControl',
    'parameters': {
    }
  })");

  EXPECT_JSON_EQ(expected, results);
}
}  // namespace weave
