// 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/states/state_change_queue.h"

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

#include "src/bind_lambda.h"

namespace weave {

using test::CreateDictionaryValue;

class StateChangeQueueTest : public ::testing::Test {
 public:
  void SetUp() override { queue_.reset(new StateChangeQueue(100)); }

  void TearDown() override { queue_.reset(); }

  std::unique_ptr<StateChangeQueue> queue_;
};

TEST_F(StateChangeQueueTest, Empty) {
  EXPECT_TRUE(queue_->IsEmpty());
  EXPECT_EQ(0u, queue_->GetLastStateChangeId());
  EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}

TEST_F(StateChangeQueueTest, UpdateOne) {
  auto timestamp = base::Time::Now();
  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp, *CreateDictionaryValue("{'prop': {'name': 23}}")));
  EXPECT_FALSE(queue_->IsEmpty());
  EXPECT_EQ(1u, queue_->GetLastStateChangeId());
  auto changes = queue_->GetAndClearRecordedStateChanges();
  EXPECT_EQ(1u, queue_->GetLastStateChangeId());
  ASSERT_EQ(1u, changes.size());
  EXPECT_EQ(timestamp, changes.front().timestamp);
  EXPECT_JSON_EQ("{'prop':{'name': 23}}", *changes.front().changed_properties);
  EXPECT_TRUE(queue_->IsEmpty());
  EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}

TEST_F(StateChangeQueueTest, UpdateMany) {
  auto timestamp1 = base::Time::Now();
  const std::string state1 = "{'prop': {'name1': 23}}";
  auto timestamp2 = timestamp1 + base::TimeDelta::FromSeconds(1);
  const std::string state2 =
      "{'prop': {'name1': 17, 'name2': 1.0, 'name3': false}}";
  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp1, *CreateDictionaryValue(state1)));
  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp2, *CreateDictionaryValue(state2)));

  EXPECT_EQ(2u, queue_->GetLastStateChangeId());
  EXPECT_FALSE(queue_->IsEmpty());
  auto changes = queue_->GetAndClearRecordedStateChanges();
  ASSERT_EQ(2u, changes.size());
  EXPECT_EQ(timestamp1, changes[0].timestamp);
  EXPECT_JSON_EQ(state1, *changes[0].changed_properties);
  EXPECT_EQ(timestamp2, changes[1].timestamp);
  EXPECT_JSON_EQ(state2, *changes[1].changed_properties);
  EXPECT_TRUE(queue_->IsEmpty());
  EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
}

TEST_F(StateChangeQueueTest, GroupByTimestamp) {
  base::Time timestamp = base::Time::Now();
  base::TimeDelta time_delta = base::TimeDelta::FromMinutes(1);

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp, *CreateDictionaryValue("{'prop': {'name1': 1}}")));

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp, *CreateDictionaryValue("{'prop': {'name2': 2}}")));

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp, *CreateDictionaryValue("{'prop': {'name1': 3}}")));

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      timestamp + time_delta,
      *CreateDictionaryValue("{'prop': {'name1': 4}}")));

  auto changes = queue_->GetAndClearRecordedStateChanges();
  EXPECT_EQ(4u, queue_->GetLastStateChangeId());
  ASSERT_EQ(2u, changes.size());

  const std::string expected1 = "{'prop': {'name1': 3, 'name2': 2}}";
  const std::string expected2 = "{'prop': {'name1': 4}}";
  EXPECT_EQ(timestamp, changes[0].timestamp);
  EXPECT_JSON_EQ(expected1, *changes[0].changed_properties);
  EXPECT_EQ(timestamp + time_delta, changes[1].timestamp);
  EXPECT_JSON_EQ(expected2, *changes[1].changed_properties);
}

TEST_F(StateChangeQueueTest, MaxQueueSize) {
  queue_.reset(new StateChangeQueue(2));
  base::Time start_time = base::Time::Now();
  base::TimeDelta time_delta1 = base::TimeDelta::FromMinutes(1);
  base::TimeDelta time_delta2 = base::TimeDelta::FromMinutes(3);

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      start_time,
      *CreateDictionaryValue("{'prop': {'name1': 1, 'name2': 2}}")));

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      start_time + time_delta1,
      *CreateDictionaryValue("{'prop': {'name1': 3, 'name3': 4}}")));

  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      start_time + time_delta2,
      *CreateDictionaryValue("{'prop': {'name10': 10, 'name11': 11}}")));

  EXPECT_EQ(3u, queue_->GetLastStateChangeId());
  auto changes = queue_->GetAndClearRecordedStateChanges();
  ASSERT_EQ(2u, changes.size());

  const std::string expected1 =
      "{'prop': {'name1': 3, 'name2': 2, 'name3': 4}}";
  EXPECT_EQ(start_time + time_delta1, changes[0].timestamp);
  EXPECT_JSON_EQ(expected1, *changes[0].changed_properties);

  const std::string expected2 =
      "{'prop': {'name10': 10, 'name11': 11}}";
  EXPECT_EQ(start_time + time_delta2, changes[1].timestamp);
  EXPECT_JSON_EQ(expected2, *changes[1].changed_properties);
}

TEST_F(StateChangeQueueTest, ImmediateStateChangeNotification) {
  // When queue is empty, registering a new callback will trigger it.
  bool called = false;
  auto callback = [&called](StateChangeQueueInterface::UpdateID id) {
    called = true;
  };
  queue_->AddOnStateUpdatedCallback(base::Bind(callback));
  EXPECT_TRUE(called);
}

TEST_F(StateChangeQueueTest, DelayedStateChangeNotification) {
  // When queue is not empty, registering a new callback will not trigger it.
  ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
      base::Time::Now(),
      *CreateDictionaryValue("{'prop': {'name1': 1, 'name3': 2}}")));

  auto callback = [](StateChangeQueueInterface::UpdateID id) {
    FAIL() << "This should not be called";
  };
  queue_->AddOnStateUpdatedCallback(base::Bind(callback));
}

}  // namespace weave
