// 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_revocation_manager.h"
#include "src/component_manager_impl.h"
#include "src/data_encoding.h"
#include "src/test/mock_access_revocation_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("blacklist.add", "blacklist.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("blacklist");
    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.blacklist", &state));
    return state->CreateDeepCopy();
  }

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

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

  auto expected = R"({
    "commands": {
      "add": {
        "minimalRole": "owner",
        "parameters": {
          "userId": {
            "type": "string"
          },
          "applicationId": {
            "type": "string"
          },
          "revocationTimestamp": {
            "type": "integer"
          },
          "expirationTime": {
            "type": "integer"
          }
        }
      },
      "list": {
        "minimalRole": "owner",
        "parameters": {},
        "results": {
          "blacklistEntries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "string"
                },
                "applicationId": {
                  "type": "string"
                },
                "revocationTimestamp": {
                  "type": "integer"
                },
                "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(AccessRevocationManager::Entry{std::vector<uint8_t>{1, 2, 3},
                                           std::vector<uint8_t>{3, 4, 5},
                                           base::Time::FromTimeT(946686034),
                                           base::Time::FromTimeT(946692690)},
            _))
      .WillOnce(WithArgs<1>(
          Invoke([](const DoneCallback& callback) { callback.Run(nullptr); })));
  EXPECT_CALL(access_manager_, GetSize()).WillRepeatedly(Return(1));

  AddCommand(R"({
    'name' : 'blacklist.add',
    'component': 'accessControl',
    'parameters': {
      'userId': 'AQID',
      'applicationId': 'AwQF',
      'expirationTime': 7890,
      'revocationTimestamp': 1234
    }
  })");

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

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

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

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

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