// Copyright (c) 2012 The Chromium 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 "components/sync/protocol/proto_value_conversions.h"

#include <string>

#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/unique_position.h"
#include "components/sync/protocol/app_setting_specifics.pb.h"
#include "components/sync/protocol/app_specifics.pb.h"
#include "components/sync/protocol/autofill_specifics.pb.h"
#include "components/sync/protocol/bookmark_specifics.pb.h"
#include "components/sync/protocol/device_info_specifics.pb.h"
#include "components/sync/protocol/encryption.pb.h"
#include "components/sync/protocol/extension_setting_specifics.pb.h"
#include "components/sync/protocol/extension_specifics.pb.h"
#include "components/sync/protocol/managed_user_setting_specifics.pb.h"
#include "components/sync/protocol/nigori_specifics.pb.h"
#include "components/sync/protocol/os_preference_specifics.pb.h"
#include "components/sync/protocol/os_priority_preference_specifics.pb.h"
#include "components/sync/protocol/password_specifics.pb.h"
#include "components/sync/protocol/preference_specifics.pb.h"
#include "components/sync/protocol/priority_preference_specifics.pb.h"
#include "components/sync/protocol/search_engine_specifics.pb.h"
#include "components/sync/protocol/session_specifics.pb.h"
#include "components/sync/protocol/sharing_message_specifics.pb.h"
#include "components/sync/protocol/sync.pb.h"
#include "components/sync/protocol/theme_specifics.pb.h"
#include "components/sync/protocol/typed_url_specifics.pb.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {
namespace {

// Keep this file in sync with the .proto files in this directory.

#define DEFINE_SPECIFICS_TO_VALUE_TEST(Key)                         \
  TEST(ProtoValueConversionsTest, Proto_##Key##_SpecificsToValue) { \
    sync_pb::EntitySpecifics specifics;                             \
    specifics.mutable_##Key();                                      \
    std::unique_ptr<base::DictionaryValue> value(                   \
        EntitySpecificsToValue(specifics));                         \
    EXPECT_EQ(1, static_cast<int>(value->DictSize()));              \
  }

// We'd also like to check if we changed any field in our messages. However,
// that's hard to do: sizeof could work, but it's platform-dependent.
// default_instance().ByteSize() won't change for most changes, since most of
// our fields are optional. So we just settle for comments in the proto files.

DEFINE_SPECIFICS_TO_VALUE_TEST(encrypted)

static_assert(37 == syncer::GetNumModelTypes(),
              "When adding a new field, add a DEFINE_SPECIFICS_TO_VALUE_TEST "
              "for your field below, and optionally a test for the specific "
              "conversions.");

DEFINE_SPECIFICS_TO_VALUE_TEST(app)
DEFINE_SPECIFICS_TO_VALUE_TEST(app_list)
DEFINE_SPECIFICS_TO_VALUE_TEST(app_setting)
DEFINE_SPECIFICS_TO_VALUE_TEST(arc_package)
DEFINE_SPECIFICS_TO_VALUE_TEST(autofill)
DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_offer)
DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_profile)
DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_wallet)
DEFINE_SPECIFICS_TO_VALUE_TEST(bookmark)
DEFINE_SPECIFICS_TO_VALUE_TEST(device_info)
DEFINE_SPECIFICS_TO_VALUE_TEST(dictionary)
DEFINE_SPECIFICS_TO_VALUE_TEST(extension)
DEFINE_SPECIFICS_TO_VALUE_TEST(extension_setting)
DEFINE_SPECIFICS_TO_VALUE_TEST(history_delete_directive)
DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_setting)
DEFINE_SPECIFICS_TO_VALUE_TEST(nigori)
DEFINE_SPECIFICS_TO_VALUE_TEST(os_preference)
DEFINE_SPECIFICS_TO_VALUE_TEST(os_priority_preference)
DEFINE_SPECIFICS_TO_VALUE_TEST(password)
DEFINE_SPECIFICS_TO_VALUE_TEST(preference)
DEFINE_SPECIFICS_TO_VALUE_TEST(printer)
DEFINE_SPECIFICS_TO_VALUE_TEST(priority_preference)
DEFINE_SPECIFICS_TO_VALUE_TEST(reading_list)
DEFINE_SPECIFICS_TO_VALUE_TEST(search_engine)
DEFINE_SPECIFICS_TO_VALUE_TEST(security_event)
DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self)
DEFINE_SPECIFICS_TO_VALUE_TEST(session)
DEFINE_SPECIFICS_TO_VALUE_TEST(sharing_message)
DEFINE_SPECIFICS_TO_VALUE_TEST(theme)
DEFINE_SPECIFICS_TO_VALUE_TEST(typed_url)
DEFINE_SPECIFICS_TO_VALUE_TEST(user_consent)
DEFINE_SPECIFICS_TO_VALUE_TEST(user_event)
DEFINE_SPECIFICS_TO_VALUE_TEST(wallet_metadata)
DEFINE_SPECIFICS_TO_VALUE_TEST(web_app)
DEFINE_SPECIFICS_TO_VALUE_TEST(wifi_configuration)

TEST(ProtoValueConversionsTest, AutofillWalletSpecificsToValue) {
  sync_pb::AutofillWalletSpecifics specifics;
  specifics.mutable_masked_card()->set_name_on_card("Igloo");
  specifics.mutable_address()->set_recipient_name("John");
  specifics.mutable_customer_data()->set_id("123456");
  specifics.mutable_cloud_token_data()->set_masked_card_id("1111");

  specifics.set_type(sync_pb::AutofillWalletSpecifics::UNKNOWN);
  auto value = AutofillWalletSpecificsToValue(specifics);
  EXPECT_FALSE(value->Get("masked_card", nullptr));
  EXPECT_FALSE(value->Get("address", nullptr));
  EXPECT_FALSE(value->Get("customer_data", nullptr));
  EXPECT_FALSE(value->Get("cloud_token_data", nullptr));

  specifics.set_type(sync_pb::AutofillWalletSpecifics::MASKED_CREDIT_CARD);
  value = AutofillWalletSpecificsToValue(specifics);
  EXPECT_TRUE(value->Get("masked_card", nullptr));
  EXPECT_FALSE(value->Get("address", nullptr));
  EXPECT_FALSE(value->Get("customer_data", nullptr));
  EXPECT_FALSE(value->Get("cloud_token_data", nullptr));

  specifics.set_type(sync_pb::AutofillWalletSpecifics::POSTAL_ADDRESS);
  value = AutofillWalletSpecificsToValue(specifics);
  EXPECT_FALSE(value->Get("masked_card", nullptr));
  EXPECT_TRUE(value->Get("address", nullptr));
  EXPECT_FALSE(value->Get("customer_data", nullptr));
  EXPECT_FALSE(value->Get("cloud_token_data", nullptr));

  specifics.set_type(sync_pb::AutofillWalletSpecifics::CUSTOMER_DATA);
  value = AutofillWalletSpecificsToValue(specifics);
  EXPECT_FALSE(value->Get("masked_card", nullptr));
  EXPECT_FALSE(value->Get("address", nullptr));
  EXPECT_TRUE(value->Get("customer_data", nullptr));
  EXPECT_FALSE(value->Get("cloud_token_data", nullptr));

  specifics.set_type(
      sync_pb::AutofillWalletSpecifics::CREDIT_CARD_CLOUD_TOKEN_DATA);
  value = AutofillWalletSpecificsToValue(specifics);
  EXPECT_FALSE(value->Get("masked_card", nullptr));
  EXPECT_FALSE(value->Get("address", nullptr));
  EXPECT_FALSE(value->Get("customer_data", nullptr));
  EXPECT_TRUE(value->Get("cloud_token_data", nullptr));
}

TEST(ProtoValueConversionsTest, BookmarkSpecificsData) {
  const base::Time creation_time(base::Time::Now());
  const std::string icon_url = "http://www.google.com/favicon.ico";
  sync_pb::BookmarkSpecifics specifics;
  specifics.set_creation_time_us(creation_time.ToInternalValue());
  specifics.set_icon_url(icon_url);
  sync_pb::MetaInfo* meta_1 = specifics.add_meta_info();
  meta_1->set_key("key1");
  meta_1->set_value("value1");
  sync_pb::MetaInfo* meta_2 = specifics.add_meta_info();
  meta_2->set_key("key2");
  meta_2->set_value("value2");

  std::unique_ptr<base::DictionaryValue> value(
      BookmarkSpecificsToValue(specifics));
  EXPECT_FALSE(value->DictEmpty());
  std::string encoded_time;
  EXPECT_TRUE(value->GetString("creation_time_us", &encoded_time));
  EXPECT_EQ(base::NumberToString(creation_time.ToInternalValue()),
            encoded_time);
  std::string encoded_icon_url;
  EXPECT_TRUE(value->GetString("icon_url", &encoded_icon_url));
  EXPECT_EQ(icon_url, encoded_icon_url);
  base::ListValue* meta_info_list;
  ASSERT_TRUE(value->GetList("meta_info", &meta_info_list));
  EXPECT_EQ(2u, meta_info_list->GetSize());
  base::DictionaryValue* meta_info;
  std::string meta_key;
  std::string meta_value;
  ASSERT_TRUE(meta_info_list->GetDictionary(0, &meta_info));
  EXPECT_TRUE(meta_info->GetString("key", &meta_key));
  EXPECT_TRUE(meta_info->GetString("value", &meta_value));
  EXPECT_EQ("key1", meta_key);
  EXPECT_EQ("value1", meta_value);
  ASSERT_TRUE(meta_info_list->GetDictionary(1, &meta_info));
  EXPECT_TRUE(meta_info->GetString("key", &meta_key));
  EXPECT_TRUE(meta_info->GetString("value", &meta_value));
  EXPECT_EQ("key2", meta_key);
  EXPECT_EQ("value2", meta_value);
}

TEST(ProtoValueConversionsTest, UniquePositionToValue) {
  sync_pb::SyncEntity entity;
  entity.mutable_unique_position()->set_custom_compressed_v1("test");

  auto value = SyncEntityToValue(entity, false);
  std::string unique_position;
  EXPECT_TRUE(value->GetString("unique_position", &unique_position));

  std::string expected_unique_position =
      UniquePosition::FromProto(entity.unique_position()).ToDebugString();
  EXPECT_EQ(expected_unique_position, unique_position);
}

TEST(ProtoValueConversionsTest, SyncEntityToValueIncludeSpecifics) {
  sync_pb::SyncEntity entity;
  entity.mutable_specifics();

  auto value = SyncEntityToValue(entity, true /* include_specifics */);
  EXPECT_TRUE(value->GetDictionary("specifics", nullptr));

  value = SyncEntityToValue(entity, false /* include_specifics */);
  EXPECT_FALSE(value->GetDictionary("specifics", nullptr));
}

namespace {
// Returns whether the given value has specifics under the entries in the given
// path.
bool ValueHasSpecifics(const base::DictionaryValue& value,
                       const std::string& path) {
  const base::ListValue* entities_list = nullptr;
  const base::DictionaryValue* entry_dictionary = nullptr;
  const base::DictionaryValue* specifics_dictionary = nullptr;

  if (!value.GetList(path, &entities_list))
    return false;

  if (!entities_list->GetDictionary(0, &entry_dictionary))
    return false;

  return entry_dictionary->GetDictionary("specifics", &specifics_dictionary);
}
}  // namespace

// Create a ClientToServerMessage with an EntitySpecifics.  Converting it to
// a value should respect the |include_specifics| flag.
TEST(ProtoValueConversionsTest, ClientToServerMessageToValue) {
  sync_pb::ClientToServerMessage message;
  sync_pb::CommitMessage* commit_message = message.mutable_commit();
  sync_pb::SyncEntity* entity = commit_message->add_entries();
  entity->mutable_specifics();

  std::unique_ptr<base::DictionaryValue> value_with_specifics(
      ClientToServerMessageToValue(message, true /* include_specifics */));
  EXPECT_FALSE(value_with_specifics->DictEmpty());
  EXPECT_TRUE(
      ValueHasSpecifics(*(value_with_specifics.get()), "commit.entries"));

  std::unique_ptr<base::DictionaryValue> value_without_specifics(
      ClientToServerMessageToValue(message, false /* include_specifics */));
  EXPECT_FALSE(value_without_specifics->DictEmpty());
  EXPECT_FALSE(
      ValueHasSpecifics(*(value_without_specifics.get()), "commit.entries"));
}

// Create a ClientToServerResponse with an EntitySpecifics.  Converting it to
// a value should respect the |include_specifics| flag.
TEST(ProtoValueConversionsTest, ClientToServerResponseToValue) {
  sync_pb::ClientToServerResponse message;
  sync_pb::GetUpdatesResponse* response = message.mutable_get_updates();
  sync_pb::SyncEntity* entity = response->add_entries();
  entity->mutable_specifics();

  std::unique_ptr<base::DictionaryValue> value_with_specifics(
      ClientToServerResponseToValue(message, true /* include_specifics */));
  EXPECT_FALSE(value_with_specifics->DictEmpty());
  EXPECT_TRUE(
      ValueHasSpecifics(*(value_with_specifics.get()), "get_updates.entries"));

  std::unique_ptr<base::DictionaryValue> value_without_specifics(
      ClientToServerResponseToValue(message, false /* include_specifics */));
  EXPECT_FALSE(value_without_specifics->DictEmpty());
  EXPECT_FALSE(ValueHasSpecifics(*(value_without_specifics.get()),
                                 "get_updates.entries"));
}

}  // namespace
}  // namespace syncer
