// 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"

namespace buffet {

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

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());
  auto expected = R"({
    'base': {
      'manufacturer': 'Skynet',
      'serialNumber': 'T1000'
    },
    'terminator': {
      'target': ''
    }
  })";
  EXPECT_JSON_EQ(expected, *mgr_->GetStateValuesAsJson(nullptr));
}

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());

  auto expected = R"({
    'base': {
      'manufacturer': 'Skynet',
      'serialNumber': 'T1000'
    },
    'power': {
      'battery_level': 0
    },
    'terminator': {
      'target': ''
    }
  })";
  EXPECT_JSON_EQ(expected, *mgr_->GetStateValuesAsJson(nullptr));
}

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));
  auto expected = R"({
    'base': {
      'manufacturer': 'Skynet',
      'serialNumber': 'T1000'
    },
    'terminator': {
      'target': 'John Connor'
    }
  })";
  EXPECT_JSON_EQ(expected, *mgr_->GetStateValuesAsJson(nullptr));
}

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
