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

#include <cstdlib>  // for abs().
#include <vector>

#include <base/values.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "buffet/commands/schema_constants.h"
#include "buffet/commands/unittest_utils.h"
#include "buffet/states/error_codes.h"
#include "buffet/states/mock_state_change_queue_interface.h"

using buffet::unittests::CreateDictionaryValue;
using buffet::unittests::ValueToString;
using testing::Return;
using testing::_;

namespace buffet {

namespace {
std::unique_ptr<base::DictionaryValue> GetTestSchema() {
  return CreateDictionaryValue(R"({
    'base': {
      'manufacturer':'string',
      'serialNumber':'string'
    },
    'terminator': {
      'target':'string'
    }
  })");
}

std::unique_ptr<base::DictionaryValue> GetTestValues() {
  return CreateDictionaryValue(R"({
    'base': {
      'manufacturer':'Skynet',
      'serialNumber':'T1000'
    }
  })");
}

}  // anonymous namespace

class StateManagerTest : public ::testing::Test {
 public:
  void SetUp() override {
    // Initial expectations.
    EXPECT_CALL(mock_state_change_queue_, IsEmpty()).Times(0);
    EXPECT_CALL(mock_state_change_queue_, NotifyPropertiesUpdated(_, _))
      .Times(0);
    EXPECT_CALL(mock_state_change_queue_, GetAndClearRecordedStateChanges())
      .Times(0);
    mgr_.reset(new StateManager(&mock_state_change_queue_));
    LoadStateDefinition(GetTestSchema().get(), "default", nullptr);
    ASSERT_TRUE(mgr_->LoadStateDefaults(*GetTestValues().get(), nullptr));
  }
  void TearDown() override {
    mgr_.reset();
  }

  void LoadStateDefinition(const base::DictionaryValue* json,
                           const std::string& category,
                           chromeos::ErrorPtr* error) {
    ASSERT_TRUE(mgr_->LoadStateDefinition(*json, category, error));
  }

  std::unique_ptr<StateManager> mgr_;
  MockStateChangeQueueInterface mock_state_change_queue_;
};

TEST(StateManager, Empty) {
  MockStateChangeQueueInterface mock_state_change_queue;
  StateManager manager(&mock_state_change_queue);
  EXPECT_TRUE(manager.GetCategories().empty());
}

TEST_F(StateManagerTest, Initialized) {
  EXPECT_EQ(std::set<std::string>{"default"}, mgr_->GetCategories());
  EXPECT_EQ("{'base':{'manufacturer':'Skynet','serialNumber':'T1000'},"
            "'terminator':{'target':''}}",
            ValueToString(mgr_->GetStateValuesAsJson(nullptr).get()));
}

TEST_F(StateManagerTest, LoadStateDefinition) {
  auto dict = CreateDictionaryValue(R"({
    'power': {
      'battery_level':'integer'
    }
  })");
  LoadStateDefinition(dict.get(), "powerd", nullptr);
  EXPECT_EQ((std::set<std::string>{"default", "powerd"}),
            mgr_->GetCategories());
  EXPECT_EQ("{'base':{'manufacturer':'Skynet','serialNumber':'T1000'},"
            "'power':{'battery_level':0},"
            "'terminator':{'target':''}}",
            ValueToString(mgr_->GetStateValuesAsJson(nullptr).get()));
}

TEST_F(StateManagerTest, SetPropertyValue) {
  native_types::Object expected_prop_set{
    {"terminator.target", unittests::make_string_prop_value("John Connor")},
  };
  base::Time timestamp = base::Time::Now();
  EXPECT_CALL(mock_state_change_queue_,
              NotifyPropertiesUpdated(timestamp, expected_prop_set))
      .WillOnce(Return(true));
  ASSERT_TRUE(mgr_->SetPropertyValue("terminator.target",
                                     std::string{"John Connor"},
                                     timestamp,
                                     nullptr));
  EXPECT_EQ("{'base':{'manufacturer':'Skynet','serialNumber':'T1000'},"
            "'terminator':{'target':'John Connor'}}",
            ValueToString(mgr_->GetStateValuesAsJson(nullptr).get()));
}

TEST_F(StateManagerTest, SetPropertyValue_Error_NoName) {
  chromeos::ErrorPtr error;
  ASSERT_FALSE(mgr_->SetPropertyValue("", int{0}, base::Time::Now(), &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPropertyNameMissing, error->GetCode());
  EXPECT_EQ("Property name is missing", error->GetMessage());
}

TEST_F(StateManagerTest, SetPropertyValue_Error_NoPackage) {
  chromeos::ErrorPtr error;
  ASSERT_FALSE(mgr_->SetPropertyValue("target", int{0}, base::Time::Now(),
                                      &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPackageNameMissing, error->GetCode());
  EXPECT_EQ("Package name is missing in the property name",
            error->GetMessage());
}

TEST_F(StateManagerTest, SetPropertyValue_Error_UnknownPackage) {
  chromeos::ErrorPtr error;
  ASSERT_FALSE(mgr_->SetPropertyValue("power.level", int{0}, base::Time::Now(),
                                      &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPropertyNotDefined, error->GetCode());
  EXPECT_EQ("Unknown state property package 'power'", error->GetMessage());
}

TEST_F(StateManagerTest, SetPropertyValue_Error_UnknownProperty) {
  chromeos::ErrorPtr error;
  ASSERT_FALSE(mgr_->SetPropertyValue("base.level", int{0}, base::Time::Now(),
                                      &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPropertyNotDefined, error->GetCode());
  EXPECT_EQ("State property 'base.level' is not defined", error->GetMessage());
}

TEST_F(StateManagerTest, GetAndClearRecordedStateChanges) {
  base::Time timestamp = base::Time::Now();
  EXPECT_CALL(mock_state_change_queue_, NotifyPropertiesUpdated(timestamp, _))
      .WillOnce(Return(true));
  ASSERT_TRUE(mgr_->SetPropertyValue("terminator.target",
                                     std::string{"John Connor"},
                                     timestamp,
                                     nullptr));
  std::vector<StateChange> expected_val;
  expected_val.emplace_back(
      timestamp,
      native_types::Object{{"terminator.target",
                            unittests::make_string_prop_value("John Connor")}});
  EXPECT_CALL(mock_state_change_queue_, GetAndClearRecordedStateChanges())
      .WillOnce(Return(expected_val));
  auto changes = mgr_->GetAndClearRecordedStateChanges();
  ASSERT_EQ(1, changes.size());
  EXPECT_EQ(expected_val.back().timestamp, changes.back().timestamp);
  EXPECT_EQ(expected_val.back().changed_properties,
            changes.back().changed_properties);
}

}  // namespace buffet
