// Copyright (c) 2012 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 "shill/property_store_unittest.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/basictypes.h>
#include <dbus-c++/dbus.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "shill/dbus_adaptor.h"
#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/property_accessor.h"
#include "shill/property_store.h"

using std::map;
using std::string;
using std::vector;
using ::testing::Values;

namespace shill {

// static
const ::DBus::Variant PropertyStoreTest::kBoolV = DBusAdaptor::BoolToVariant(0);
// static
const ::DBus::Variant PropertyStoreTest::kByteV = DBusAdaptor::ByteToVariant(0);
// static
const ::DBus::Variant PropertyStoreTest::kInt16V =
    DBusAdaptor::Int16ToVariant(0);
// static
const ::DBus::Variant PropertyStoreTest::kInt32V =
    DBusAdaptor::Int32ToVariant(0);
// static
const ::DBus::Variant PropertyStoreTest::kKeyValueStoreV =
    DBusAdaptor::KeyValueStoreToVariant(KeyValueStore());
// static
const ::DBus::Variant PropertyStoreTest::kStringV =
    DBusAdaptor::StringToVariant("");
// static
const ::DBus::Variant PropertyStoreTest::kStringmapV =
    DBusAdaptor::StringmapToVariant(Stringmap());
// static
const ::DBus::Variant PropertyStoreTest::kStringmapsV =
    DBusAdaptor::StringmapsToVariant(Stringmaps());
// static
const ::DBus::Variant PropertyStoreTest::kStringsV =
    DBusAdaptor::StringsToVariant(Strings(1, ""));
// static
const ::DBus::Variant PropertyStoreTest::kUint16V =
    DBusAdaptor::Uint16ToVariant(0);
// static
const ::DBus::Variant PropertyStoreTest::kUint32V =
    DBusAdaptor::Uint32ToVariant(0);

PropertyStoreTest::PropertyStoreTest()
    : internal_error_(Error::GetName(Error::kInternalError)),
      invalid_args_(Error::GetName(Error::kInvalidArguments)),
      invalid_prop_(Error::GetName(Error::kInvalidProperty)),
      path_(dir_.CreateUniqueTempDir() ? dir_.path().value() : ""),
      manager_(control_interface(),
               dispatcher(),
               metrics(),
               glib(),
               run_path(),
               storage_path(),
               string()) {
}

PropertyStoreTest::~PropertyStoreTest() {}

void PropertyStoreTest::SetUp() {
  ASSERT_FALSE(run_path().empty());
  ASSERT_FALSE(storage_path().empty());
}

TEST_P(PropertyStoreTest, TestProperty) {
  // Ensure that an attempt to write unknown properties returns InvalidProperty.
  PropertyStore store;
  ::DBus::Error error;
  EXPECT_FALSE(DBusAdaptor::SetProperty(&store, "", GetParam(), &error));
  EXPECT_EQ(invalid_prop(), error.name());
}

INSTANTIATE_TEST_CASE_P(
    PropertyStoreTestInstance,
    PropertyStoreTest,
    Values(PropertyStoreTest::kBoolV,
           PropertyStoreTest::kByteV,
           PropertyStoreTest::kInt16V,
           PropertyStoreTest::kInt32V,
           PropertyStoreTest::kStringV,
           PropertyStoreTest::kStringmapV,
           PropertyStoreTest::kStringsV,
           PropertyStoreTest::kUint16V,
           PropertyStoreTest::kUint32V));

template <typename T>
class PropertyStoreTypedTest : public PropertyStoreTest {
 protected:
  void RegisterProperty(
      PropertyStore &store, const string &name, T *storage);
};

typedef ::testing::Types<
  bool, int16, int32, KeyValueStore, string, Stringmap, Stringmaps, Strings,
  uint8, uint16, uint32> PropertyTypes;
TYPED_TEST_CASE(PropertyStoreTypedTest, PropertyTypes);

TYPED_TEST(PropertyStoreTypedTest, ClearProperty) {
  PropertyStore store;
  Error error;
  TypeParam property;
  RegisterProperty(store, "some property", &property);
  EXPECT_TRUE(store.ClearProperty("some property", &error));
}

template<> void PropertyStoreTypedTest<bool>::RegisterProperty(
    PropertyStore &store, const string &name, bool *storage) {
  store.RegisterBool(name, storage);
}

template<> void PropertyStoreTypedTest<int16>::RegisterProperty(
    PropertyStore &store, const string &name, int16 *storage) {
  store.RegisterInt16(name, storage);
}

template<> void PropertyStoreTypedTest<int32>::RegisterProperty(
    PropertyStore &store, const string &name, int32 *storage) {
  store.RegisterInt32(name, storage);
}

template<> void PropertyStoreTypedTest<KeyValueStore>::RegisterProperty(
    PropertyStore &store, const string &name, KeyValueStore *storage) {
  // We use |RegisterDerivedKeyValueStore|, because there is no non-derived
  // version. (And it's not clear that we'll need one, outside of this
  // test.)
  store.RegisterDerivedKeyValueStore(
      name, KeyValueStoreAccessor(
          new PropertyAccessor<KeyValueStore>(storage)));
}

template<> void PropertyStoreTypedTest<string>::RegisterProperty(
    PropertyStore &store, const string &name, string *storage) {
  store.RegisterString(name, storage);
}

template<> void PropertyStoreTypedTest<Stringmap>::RegisterProperty(
    PropertyStore &store, const string &name, Stringmap *storage) {
  store.RegisterStringmap(name, storage);
}

template<> void PropertyStoreTypedTest<Stringmaps>::RegisterProperty(
    PropertyStore &store, const string &name, Stringmaps *storage) {
  store.RegisterStringmaps(name, storage);
}

template<> void PropertyStoreTypedTest<Strings>::RegisterProperty(
    PropertyStore &store, const string &name, Strings *storage) {
  store.RegisterStrings(name, storage);
}

template<> void PropertyStoreTypedTest<uint8>::RegisterProperty(
    PropertyStore &store, const string &name, uint8 *storage) {
  store.RegisterUint8(name, storage);
}

template<> void PropertyStoreTypedTest<uint16>::RegisterProperty(
    PropertyStore &store, const string &name, uint16 *storage) {
  store.RegisterUint16(name, storage);
}

template<> void PropertyStoreTypedTest<uint32>::RegisterProperty(
    PropertyStore &store, const string &name, uint32 *storage) {
  store.RegisterUint32(name, storage);
}

TEST_F(PropertyStoreTest, ClearBoolProperty) {
  // We exercise both possibilities for the default value here,
  // to ensure that Clear actually resets the property based on
  // the property's initial value (rather than the language's
  // default value for the type).
  static const bool kDefaults[] = {true, false};
  for (size_t i = 0; i < arraysize(kDefaults); ++i) {
    PropertyStore store;
    Error error;

    const bool default_value = kDefaults[i];
    bool flag = default_value;
    store.RegisterBool("some bool", &flag);

    EXPECT_TRUE(store.ClearProperty("some bool", &error));
    EXPECT_EQ(default_value, flag);
  }
}

TEST_F(PropertyStoreTest, ClearPropertyNonexistent) {
  PropertyStore store;
  Error error;

  EXPECT_FALSE(store.ClearProperty("", &error));
  EXPECT_EQ(Error::kInvalidProperty, error.type());
}

TEST_F(PropertyStoreTest, SetStringmapsProperty) {
  PropertyStore store;
  ::DBus::Error error;
  EXPECT_FALSE(DBusAdaptor::SetProperty(
      &store, "", PropertyStoreTest::kStringmapsV, &error));
  EXPECT_EQ(internal_error(), error.name());
}

TEST_F(PropertyStoreTest, SetKeyValueStoreProperty) {
  PropertyStore store;
  ::DBus::Error error;
  EXPECT_FALSE(DBusAdaptor::SetProperty(
      &store, "", PropertyStoreTest::kKeyValueStoreV, &error));
  EXPECT_EQ(internal_error(), error.name());
}

TEST_F(PropertyStoreTest, WriteOnlyProperties) {
  // Test that properties registered as write-only are not returned
  // when using Get*PropertiesIter().
  PropertyStore store;
  Error error;
  {
    const string keys[]  = {"boolp1", "boolp2"};
    bool values[] = {true, true};
    store.RegisterWriteOnlyBool(keys[0], &values[0]);
    store.RegisterBool(keys[1], &values[1]);

    ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_TRUE(values[1] == it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"int16p1", "int16p2"};
    int16 values[] = {127, 128};
    store.RegisterWriteOnlyInt16(keys[0], &values[0]);
    store.RegisterInt16(keys[1], &values[1]);

    ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_EQ(values[1], it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"int32p1", "int32p2"};
    int32 values[] = {127, 128};
    store.RegisterWriteOnlyInt32(keys[0], &values[0]);
    store.RegisterInt32(keys[1], &values[1]);

    ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_EQ(values[1], it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"stringp1", "stringp2"};
    string values[] = {"noooo", "yesss"};
    store.RegisterWriteOnlyString(keys[0], &values[0]);
    store.RegisterString(keys[1], &values[1]);

    ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_EQ(values[1], it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"stringmapp1", "stringmapp2"};
    Stringmap values[2];
    values[0]["noooo"] = "yesss";
    values[1]["yesss"] = "noooo";
    store.RegisterWriteOnlyStringmap(keys[0], &values[0]);
    store.RegisterStringmap(keys[1], &values[1]);

    ReadablePropertyConstIterator<Stringmap> it =
        store.GetStringmapPropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_TRUE(values[1] == it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"stringmapsp1", "stringmapsp2"};
    Stringmaps values[2];
    Stringmap element;
    element["noooo"] = "yesss";
    values[0].push_back(element);
    element["yesss"] = "noooo";
    values[1].push_back(element);

    store.RegisterWriteOnlyStringmaps(keys[0], &values[0]);
    store.RegisterStringmaps(keys[1], &values[1]);

    ReadablePropertyConstIterator<Stringmaps> it =
        store.GetStringmapsPropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_TRUE(values[1] == it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"stringsp1", "stringsp2"};
    Strings values[2];
    string element;
    element = "noooo";
    values[0].push_back(element);
    element = "yesss";
    values[1].push_back(element);
    store.RegisterWriteOnlyStrings(keys[0], &values[0]);
    store.RegisterStrings(keys[1], &values[1]);

    ReadablePropertyConstIterator<Strings> it =
        store.GetStringsPropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_TRUE(values[1] == it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"uint8p1", "uint8p2"};
    uint8 values[] = {127, 128};
    store.RegisterWriteOnlyUint8(keys[0], &values[0]);
    store.RegisterUint8(keys[1], &values[1]);

    ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_EQ(values[1], it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
  {
    const string keys[] = {"uint16p", "uint16p1"};
    uint16 values[] = {127, 128};
    store.RegisterWriteOnlyUint16(keys[0], &values[0]);
    store.RegisterUint16(keys[1], &values[1]);

    ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
    error.Reset();
    EXPECT_FALSE(it.AtEnd());
    EXPECT_EQ(keys[1], it.Key());
    EXPECT_EQ(values[1], it.Value(&error));
    EXPECT_TRUE(error.IsSuccess());
    it.Advance();
    EXPECT_TRUE(it.AtEnd());
  }
}

}  // namespace shill
