// Copyright 2014 The Chromium OS 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 "buffet/commands/command_queue.h"

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

#include <chromeos/strings/string_utils.h>
#include <gtest/gtest.h>

#include "buffet/commands/command_definition.h"
#include "buffet/commands/command_dispatch_interface.h"
#include "buffet/commands/object_schema.h"

namespace buffet {

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, "local", &command_definition_, {}}};
    cmd->SetID(id);
    return cmd;
  }

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

  void Cleanup(const base::TimeDelta& interval) {
    queue_.SetNowForTest(base::Time::Now() + interval);
    return queue_.Cleanup();
  }

  CommandQueue queue_;

 private:
  CommandDefinition command_definition_{"powerd",
                                        ObjectSchema::Create(),
                                        ObjectSchema::Create(),
                                        ObjectSchema::Create()};
};

// Fake implementation of CommandDispachInterface.
// Just 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 FakeDispatchInterface : public CommandDispachInterface {
 public:
  void OnCommandAdded(CommandInstance* command_instance) override {
    CHECK(ids_.insert(command_instance->GetID()).second)
        << "Command ID already exists: " << command_instance->GetID();
    CHECK(commands_.insert(command_instance).second)
        << "Command instance already exists";
  }

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

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

 private:
  std::set<std::string> ids_;
  std::set<CommandInstance*> commands_;
};

TEST_F(CommandQueueTest, Empty) {
  EXPECT_TRUE(queue_.IsEmpty());
  EXPECT_EQ(0, 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(3, 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(2, queue_.GetCount());
  EXPECT_TRUE(Remove(id1));
  EXPECT_EQ(1, queue_.GetCount());
  EXPECT_FALSE(Remove(id1));
  EXPECT_EQ(1, queue_.GetCount());
  EXPECT_TRUE(Remove(id2));
  EXPECT_EQ(0, queue_.GetCount());
  EXPECT_FALSE(Remove(id2));
  EXPECT_EQ(0, queue_.GetCount());
  EXPECT_TRUE(queue_.IsEmpty());
}

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

  queue_.DelayedRemove(id1);
  EXPECT_EQ(1, queue_.GetCount());

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

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

TEST_F(CommandQueueTest, Dispatch) {
  FakeDispatchInterface dispatch;
  queue_.SetCommandDispachInterface(&dispatch);
  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 = chromeos::string_utils::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());
  queue_.SetCommandDispachInterface(nullptr);
}

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 buffet
