// 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/commands/command_queue.h"

#include <set>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/memory/weak_ptr.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>

#include "src/bind_lambda.h"
#include "src/string_utils.h"

namespace weave {

using testing::Return;
using testing::StrictMock;

class CommandQueueTest : public testing::Test {
 public:
  std::unique_ptr<CommandInstance> CreateDummyCommandInstance(
      const std::string& name,
      const std::string& id) {
    std::unique_ptr<CommandInstance> cmd{
        new CommandInstance{name, Command::Origin::kLocal, {}}};
    cmd->SetID(id);
    return cmd;
  }

  bool Remove(const std::string& id) { return queue_.Remove(id); }

  void Cleanup(const base::TimeDelta& interval) {
    return queue_.Cleanup(task_runner_.GetClock()->Now() + interval);
  }

  std::string GetFirstCommandToBeRemoved() const {
    return queue_.remove_queue_.top().second;
  }

  StrictMock<provider::test::FakeTaskRunner> task_runner_;
  CommandQueue queue_{&task_runner_, task_runner_.GetClock()};
};

// Keeps track of commands being added to and removed from the queue_.
// Aborts if duplicate commands are added or non-existent commands are removed.
class FakeDispatcher {
 public:
  explicit FakeDispatcher(CommandQueue* queue) {
    queue->AddCommandAddedCallback(base::Bind(&FakeDispatcher::OnCommandAdded,
                                              weak_ptr_factory_.GetWeakPtr()));
    queue->AddCommandRemovedCallback(base::Bind(
        &FakeDispatcher::OnCommandRemoved, weak_ptr_factory_.GetWeakPtr()));
  }

  void OnCommandAdded(Command* command) {
    CHECK(ids_.insert(command->GetID()).second) << "Command ID already exists: "
                                                << command->GetID();
    CHECK(commands_.insert(command).second)
        << "Command instance already exists";
  }

  void OnCommandRemoved(Command* command) {
    CHECK_EQ(1u, ids_.erase(command->GetID())) << "Command ID not found: "
                                               << command->GetID();
    CHECK_EQ(1u, commands_.erase(command)) << "Command instance not found";
  }

  // Get the comma-separated list of command IDs currently accumulated in the
  // command queue_.
  std::string GetIDs() const {
    return Join(",", std::vector<std::string>(ids_.begin(), ids_.end()));
  }

 private:
  std::set<std::string> ids_;
  std::set<Command*> commands_;
  base::WeakPtrFactory<FakeDispatcher> weak_ptr_factory_{this};
};

TEST_F(CommandQueueTest, Empty) {
  EXPECT_TRUE(queue_.IsEmpty());
  EXPECT_EQ(0u, queue_.GetCount());
}

TEST_F(CommandQueueTest, Add) {
  queue_.Add(CreateDummyCommandInstance("base.reboot", "id1"));
  queue_.Add(CreateDummyCommandInstance("base.reboot", "id2"));
  queue_.Add(CreateDummyCommandInstance("base.reboot", "id3"));
  EXPECT_EQ(3u, queue_.GetCount());
  EXPECT_FALSE(queue_.IsEmpty());
}

TEST_F(CommandQueueTest, Remove) {
  const std::string id1 = "id1";
  const std::string id2 = "id2";
  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
  EXPECT_FALSE(queue_.IsEmpty());
  EXPECT_FALSE(Remove("dummy"));
  EXPECT_EQ(2u, queue_.GetCount());
  EXPECT_TRUE(Remove(id1));
  EXPECT_EQ(1u, queue_.GetCount());
  EXPECT_FALSE(Remove(id1));
  EXPECT_EQ(1u, queue_.GetCount());
  EXPECT_TRUE(Remove(id2));
  EXPECT_EQ(0u, queue_.GetCount());
  EXPECT_FALSE(Remove(id2));
  EXPECT_EQ(0u, queue_.GetCount());
  EXPECT_TRUE(queue_.IsEmpty());
}

TEST_F(CommandQueueTest, RemoveLater) {
  const std::string id1 = "id1";
  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  EXPECT_EQ(1u, queue_.GetCount());

  queue_.RemoveLater(id1);
  EXPECT_EQ(1u, queue_.GetCount());

  Cleanup(base::TimeDelta::FromMinutes(1));
  EXPECT_EQ(1u, queue_.GetCount());

  Cleanup(base::TimeDelta::FromMinutes(15));
  EXPECT_EQ(0u, queue_.GetCount());
}

TEST_F(CommandQueueTest, RemoveLaterOnCleanupTask) {
  const std::string id1 = "id1";
  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  EXPECT_EQ(1u, queue_.GetCount());

  queue_.RemoveLater(id1);
  EXPECT_EQ(1u, queue_.GetCount());
  ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());

  task_runner_.RunOnce();

  EXPECT_EQ(0u, queue_.GetCount());
  EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
}

TEST_F(CommandQueueTest, CleanupMultipleCommands) {
  const std::string id1 = "id1";
  const std::string id2 = "id2";

  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
  auto remove_task = [](CommandQueue* queue, const std::string& id) {
    queue->RemoveLater(id);
  };
  remove_task(&queue_, id1);
  task_runner_.PostDelayedTask(
      FROM_HERE, base::Bind(remove_task, base::Unretained(&queue_), id2),
      base::TimeDelta::FromSeconds(10));
  EXPECT_EQ(2u, queue_.GetCount());
  ASSERT_EQ(2u, task_runner_.GetTaskQueueSize());
  task_runner_.RunOnce();  // Executes "remove_task(id2) @ T+10s".
  ASSERT_EQ(2u, queue_.GetCount());
  ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
  EXPECT_EQ(id1, GetFirstCommandToBeRemoved());
  task_runner_.RunOnce();  // Should remove task "id1" from queue.
  ASSERT_EQ(1u, queue_.GetCount());
  ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
  EXPECT_EQ(id2, GetFirstCommandToBeRemoved());
  task_runner_.RunOnce();  // Should remove task "id2" from queue.
  EXPECT_EQ(0u, queue_.GetCount());
  EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
}

TEST_F(CommandQueueTest, Dispatch) {
  FakeDispatcher dispatch(&queue_);
  const std::string id1 = "id1";
  const std::string id2 = "id2";
  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
  std::set<std::string> ids{id1, id2};  // Make sure they are sorted properly.
  std::string expected_set =
      Join(",", std::vector<std::string>(ids.begin(), ids.end()));
  EXPECT_EQ(expected_set, dispatch.GetIDs());
  Remove(id1);
  EXPECT_EQ(id2, dispatch.GetIDs());
  Remove(id2);
  EXPECT_EQ("", dispatch.GetIDs());
}

TEST_F(CommandQueueTest, Find) {
  const std::string id1 = "id1";
  const std::string id2 = "id2";
  queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
  queue_.Add(CreateDummyCommandInstance("base.shutdown", id2));
  EXPECT_EQ(nullptr, queue_.Find("dummy"));
  auto cmd1 = queue_.Find(id1);
  EXPECT_NE(nullptr, cmd1);
  EXPECT_EQ("base.reboot", cmd1->GetName());
  EXPECT_EQ(id1, cmd1->GetID());
  auto cmd2 = queue_.Find(id2);
  EXPECT_NE(nullptr, cmd2);
  EXPECT_EQ("base.shutdown", cmd2->GetName());
  EXPECT_EQ(id2, cmd2->GetID());
}

}  // namespace weave
