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

#include <memory>
#include <string>

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

#include "src/commands/schema_constants.h"
#include "src/commands/unittest_utils.h"
#include "src/states/error_codes.h"

namespace weave {

using test::CreateDictionaryValue;

class StatePackageTestHelper {
 public:
  // Returns the state property definitions (types/constraints/etc).
  static const base::DictionaryValue& GetTypes(const StatePackage& package) {
    return package.types_;
  }
  // Returns the all state property values in this package.
  static const base::DictionaryValue& GetValues(const StatePackage& package) {
    return package.values_;
  }
};

namespace {
std::unique_ptr<base::DictionaryValue> GetTestSchema() {
  return CreateDictionaryValue(R"({
    'color': {
      'type': 'string'
    },
    'direction': {
      'additionalProperties': false,
      'properties': {
        'altitude': {
          'maximum': 90.0,
          'type': 'number'
        },
        'azimuth': {
          'type': 'number'
        }
      },
      'type': 'object',
      'required': [ 'azimuth' ]
    },
    'iso': {
      'enum': [50, 100, 200, 400],
      'type': 'integer'
    },
    'light': {
      'type': 'boolean'
    }
  })");
}

std::unique_ptr<base::DictionaryValue> GetTestValues() {
  return CreateDictionaryValue(R"({
      'light': true,
      'color': 'white',
      'direction': {'azimuth':57.2957795, 'altitude':89.9},
      'iso': 200
  })");
}

inline const base::DictionaryValue& GetTypes(const StatePackage& package) {
  return StatePackageTestHelper::GetTypes(package);
}
// Returns the all state property values in this package.
inline const base::DictionaryValue& GetValues(const StatePackage& package) {
  return StatePackageTestHelper::GetValues(package);
}

}  // anonymous namespace

class StatePackageTest : public ::testing::Test {
 public:
  void SetUp() override {
    package_.reset(new StatePackage("test"));
    ASSERT_TRUE(package_->AddSchemaFromJson(GetTestSchema().get(), nullptr));
    ASSERT_TRUE(package_->AddValuesFromJson(GetTestValues().get(), nullptr));
  }
  void TearDown() override { package_.reset(); }
  std::unique_ptr<StatePackage> package_;
};

TEST(StatePackage, Empty) {
  StatePackage package("test");
  EXPECT_EQ("test", package.GetName());
  EXPECT_TRUE(GetTypes(package).empty());
  EXPECT_TRUE(GetValues(package).empty());
}

TEST(StatePackage, AddSchemaFromJson_OnEmpty) {
  StatePackage package("test");
  ASSERT_TRUE(package.AddSchemaFromJson(GetTestSchema().get(), nullptr));
  EXPECT_EQ(4u, GetTypes(package).size());
  EXPECT_EQ(0u, GetValues(package).size());

  auto expected = R"({
    'color': {
      'type': 'string'
    },
    'direction': {
      'additionalProperties': false,
      'properties': {
        'altitude': {
          'maximum': 90.0,
          'type': 'number'
        },
        'azimuth': {
          'type': 'number'
        }
      },
      'type': 'object',
      'required': [ 'azimuth' ]
    },
    'iso': {
      'enum': [50, 100, 200, 400],
      'type': 'integer'
    },
    'light': {
      'type': 'boolean'
    }
  })";
  EXPECT_JSON_EQ(expected, GetTypes(package));

  EXPECT_JSON_EQ("{}", *package.GetValuesAsJson());
}

TEST(StatePackage, AddValuesFromJson_OnEmpty) {
  StatePackage package("test");
  ASSERT_TRUE(package.AddSchemaFromJson(GetTestSchema().get(), nullptr));
  ASSERT_TRUE(package.AddValuesFromJson(GetTestValues().get(), nullptr));
  EXPECT_EQ(4u, GetValues(package).size());
  auto expected = R"({
    'color': 'white',
    'direction': {
      'altitude': 89.9,
      'azimuth': 57.2957795
    },
    'iso': 200,
    'light': true
  })";
  EXPECT_JSON_EQ(expected, *package.GetValuesAsJson());
}

TEST_F(StatePackageTest, AddSchemaFromJson_AddMore) {
  auto dict = CreateDictionaryValue(R"({'brightness':{
      'enum': ['low', 'medium', 'high'],
      'type': 'string'
    }})");
  ASSERT_TRUE(package_->AddSchemaFromJson(dict.get(), nullptr));
  EXPECT_EQ(5u, GetTypes(*package_).size());
  EXPECT_EQ(4u, GetValues(*package_).size());
  auto expected = R"({
    'brightness': {
      'enum': ['low', 'medium', 'high'],
      'type': 'string'
    },
    'color': {
      'type': 'string'
    },
    'direction': {
      'additionalProperties': false,
      'properties': {
        'altitude': {
          'maximum': 90.0,
          'type': 'number'
        },
        'azimuth': {
          'type': 'number'
        }
      },
      'type': 'object',
      'required': [ 'azimuth' ]
    },
    'iso': {
      'enum': [50, 100, 200, 400],
      'type': 'integer'
    },
    'light': {
      'type': 'boolean'
    }
  })";
  EXPECT_JSON_EQ(expected, GetTypes(*package_));

  expected = R"({
    'color': 'white',
    'direction': {
      'altitude': 89.9,
      'azimuth': 57.2957795
    },
    'iso': 200,
    'light': true
  })";
  EXPECT_JSON_EQ(expected, *package_->GetValuesAsJson());
}

TEST_F(StatePackageTest, AddValuesFromJson_AddMore) {
  auto dict = CreateDictionaryValue(R"({'brightness':{
      'enum': ['low', 'medium', 'high'],
      'type': 'string'
    }})");
  ASSERT_TRUE(package_->AddSchemaFromJson(dict.get(), nullptr));
  dict = CreateDictionaryValue("{'brightness':'medium'}");
  ASSERT_TRUE(package_->AddValuesFromJson(dict.get(), nullptr));
  EXPECT_EQ(5u, GetValues(*package_).size());
  auto expected = R"({
    'brightness': 'medium',
    'color': 'white',
    'direction': {
      'altitude': 89.9,
      'azimuth': 57.2957795
    },
    'iso': 200,
    'light': true
  })";
  EXPECT_JSON_EQ(expected, *package_->GetValuesAsJson());
}

TEST_F(StatePackageTest, AddSchemaFromJson_Error_Redefined) {
  auto dict = CreateDictionaryValue(R"({'color':
    {'type':'string', 'enum':['white', 'blue', 'red']}})");
  ErrorPtr error;
  EXPECT_FALSE(package_->AddSchemaFromJson(dict.get(), &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPropertyRedefinition, error->GetCode());
}

TEST_F(StatePackageTest, AddValuesFromJson_Error_Undefined) {
  auto dict = CreateDictionaryValue("{'brightness':'medium'}");
  EXPECT_TRUE(package_->AddValuesFromJson(dict.get(), nullptr));
}

TEST_F(StatePackageTest, GetPropertyValue) {
  EXPECT_JSON_EQ("'white'", *package_->GetPropertyValue("color", nullptr));
  EXPECT_JSON_EQ("true", *package_->GetPropertyValue("light", nullptr));
  EXPECT_JSON_EQ("200", *package_->GetPropertyValue("iso", nullptr));
  EXPECT_JSON_EQ("{'altitude': 89.9, 'azimuth': 57.2957795}",
                 *package_->GetPropertyValue("direction", nullptr));
}

TEST_F(StatePackageTest, GetPropertyValue_Unknown) {
  ErrorPtr error;
  EXPECT_EQ(nullptr, package_->GetPropertyValue("volume", &error));
  EXPECT_EQ(errors::state::kDomain, error->GetDomain());
  EXPECT_EQ(errors::state::kPropertyNotDefined, error->GetCode());
}

TEST_F(StatePackageTest, SetPropertyValue_Simple) {
  EXPECT_TRUE(
      package_->SetPropertyValue("color", base::StringValue{"blue"}, nullptr));
  EXPECT_JSON_EQ("'blue'", *package_->GetPropertyValue("color", nullptr));
  EXPECT_TRUE(package_->SetPropertyValue("light", base::FundamentalValue{false},
                                         nullptr));
  bool light = false;
  ASSERT_TRUE(
      package_->GetPropertyValue("light", nullptr)->GetAsBoolean(&light));
  EXPECT_FALSE(light);
  EXPECT_TRUE(
      package_->SetPropertyValue("iso", base::FundamentalValue{400}, nullptr));
  EXPECT_JSON_EQ("400", *package_->GetPropertyValue("iso", nullptr));
}

TEST_F(StatePackageTest, SetPropertyValue_Object) {
  EXPECT_TRUE(package_->SetPropertyValue(
      "direction",
      *CreateDictionaryValue("{'altitude': 45.0, 'azimuth': 15.0}"), nullptr));

  auto expected = R"({
    'color': 'white',
    'direction': {
      'altitude': 45.0,
      'azimuth': 15.0
    },
    'iso': 200,
    'light': true
  })";
  EXPECT_JSON_EQ(expected, *package_->GetValuesAsJson());
}

}  // namespace weave
