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

#include <utility>

#include "base/json/string_escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "components/sync/base/cryptographer.h"
#include "components/sync/protocol/proto_memory_estimations.h"
#include "components/sync/protocol/proto_value_conversions.h"
#include "components/sync/syncable/syncable_columns.h"
#include "components/sync/syncable/syncable_enum_conversions.h"

namespace syncer {
namespace syncable {

EntryKernel::EntryKernel() : dirty_(false), memory_usage_(kMemoryUsageUnknown) {
  // Everything else should already be default-initialized.
  for (int i = 0; i < INT64_FIELDS_COUNT; ++i) {
    int64_fields[i] = 0;
  }
}

EntryKernel::EntryKernel(const EntryKernel& other) = default;

EntryKernel::~EntryKernel() {}

ModelType EntryKernel::GetModelType() const {
  ModelType specifics_type = GetModelTypeFromSpecifics(ref(SPECIFICS));
  if (specifics_type != UNSPECIFIED)
    return specifics_type;
  if (ref(ID).IsRoot())
    return TOP_LEVEL_FOLDER;
  // Loose check for server-created top-level folders that aren't
  // bound to a particular model type.
  if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR))
    return TOP_LEVEL_FOLDER;

  return UNSPECIFIED;
}

ModelType EntryKernel::GetServerModelType() const {
  ModelType specifics_type = GetModelTypeFromSpecifics(ref(SERVER_SPECIFICS));
  if (specifics_type != UNSPECIFIED)
    return specifics_type;
  if (ref(ID).IsRoot())
    return TOP_LEVEL_FOLDER;
  // Loose check for server-created top-level folders that aren't
  // bound to a particular model type.
  if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR))
    return TOP_LEVEL_FOLDER;

  return UNSPECIFIED;
}

bool EntryKernel::ShouldMaintainPosition() const {
  // We maintain positions for all bookmarks, except those that are
  // server-created top-level folders.
  return TypeSupportsOrdering(GetModelTypeFromSpecifics(ref(SPECIFICS))) &&
         !(!ref(UNIQUE_SERVER_TAG).empty() && ref(IS_DIR));
}

bool EntryKernel::ShouldMaintainHierarchy() const {
  // We maintain hierarchy for bookmarks and top-level folders,
  // but no other types.  Note that the Nigori node consists of a single
  // top-level folder, so it's included in this set.
  return TypeSupportsHierarchy(GetModelTypeFromSpecifics(ref(SPECIFICS))) ||
         (!ref(UNIQUE_SERVER_TAG).empty());
}

namespace {

// Utility function to loop through a set of enum values and add the
// field keys/values in the kernel to the given dictionary.
//
// V should be convertible to Value.
template <class T, class U, class V>
void SetFieldValues(const EntryKernel& kernel,
                    base::DictionaryValue* dictionary_value,
                    const char* (*enum_key_fn)(T),
                    std::unique_ptr<V> (*enum_value_fn)(U),
                    int field_key_min,
                    int field_key_max) {
  DCHECK_LE(field_key_min, field_key_max);
  for (int i = field_key_min; i <= field_key_max; ++i) {
    T field = static_cast<T>(i);
    const std::string& key = enum_key_fn(field);
    std::unique_ptr<V> value = enum_value_fn(kernel.ref(field));
    dictionary_value->Set(key, std::move(value));
  }
}

void SetEncryptableProtoValues(const EntryKernel& kernel,
                               Cryptographer* cryptographer,
                               base::DictionaryValue* dictionary_value,
                               int field_key_min,
                               int field_key_max) {
  DCHECK_LE(field_key_min, field_key_max);
  for (int i = field_key_min; i <= field_key_max; ++i) {
    ProtoField field = static_cast<ProtoField>(i);
    const std::string& key = GetProtoFieldString(field);

    std::unique_ptr<base::DictionaryValue> value;
    sync_pb::EntitySpecifics decrypted;
    const sync_pb::EncryptedData& encrypted = kernel.ref(field).encrypted();
    if (cryptographer && kernel.ref(field).has_encrypted() &&
        cryptographer->CanDecrypt(encrypted) &&
        cryptographer->Decrypt(encrypted, &decrypted)) {
      value = EntitySpecificsToValue(decrypted);
      value->SetBoolean("encrypted", true);
    } else {
      value = EntitySpecificsToValue(kernel.ref(field));
    }
    dictionary_value->Set(key, std::move(value));
  }
}

// Helper functions for SetFieldValues().

std::unique_ptr<base::Value> Int64ToValue(int64_t i) {
  return std::make_unique<base::Value>(base::Int64ToString(i));
}

std::unique_ptr<base::Value> TimeToValue(const base::Time& t) {
  return std::make_unique<base::Value>(GetTimeDebugString(t));
}

std::unique_ptr<base::Value> IdToValue(const Id& id) {
  return id.ToValue();
}

std::unique_ptr<base::Value> BooleanToValue(bool bool_val) {
  return std::make_unique<base::Value>(bool_val);
}

std::unique_ptr<base::Value> StringToValue(const std::string& str) {
  return std::make_unique<base::Value>(str);
}

std::unique_ptr<base::Value> UniquePositionToValue(const UniquePosition& pos) {
  return std::make_unique<base::Value>(pos.ToDebugString());
}

// Estimates memory usage of ProtoValuePtr<T> arrays where consecutive
// elements can share the same value.
template <class T, size_t N>
size_t EstimateSharedMemoryUsage(ProtoValuePtr<T> const (&ptrs)[N]) {
  size_t memory_usage = 0;
  const T* last_value = nullptr;
  for (const auto& ptr : ptrs) {
    if (last_value != &ptr.value()) {
      memory_usage += EstimateMemoryUsage(ptr);
      last_value = &ptr.value();
    }
  }
  return memory_usage;
}

}  // namespace

std::unique_ptr<base::DictionaryValue> EntryKernel::ToValue(
    Cryptographer* cryptographer) const {
  auto kernel_info = std::make_unique<base::DictionaryValue>();
  kernel_info->SetBoolean("isDirty", is_dirty());
  ModelType dataType = GetServerModelType();
  if (!IsRealDataType(dataType))
    dataType = GetModelType();
  kernel_info->Set("modelType", ModelTypeToValue(dataType));

  // Int64 fields.
  SetFieldValues(*this, kernel_info.get(), &GetMetahandleFieldString,
                 &Int64ToValue, INT64_FIELDS_BEGIN, META_HANDLE);
  SetFieldValues(*this, kernel_info.get(), &GetBaseVersionString, &Int64ToValue,
                 META_HANDLE + 1, BASE_VERSION);
  SetFieldValues(*this, kernel_info.get(), &GetInt64FieldString, &Int64ToValue,
                 BASE_VERSION + 1, INT64_FIELDS_END - 1);

  // Time fields.
  SetFieldValues(*this, kernel_info.get(), &GetTimeFieldString, &TimeToValue,
                 TIME_FIELDS_BEGIN, TIME_FIELDS_END - 1);

  // ID fields.
  SetFieldValues(*this, kernel_info.get(), &GetIdFieldString, &IdToValue,
                 ID_FIELDS_BEGIN, ID_FIELDS_END - 1);

  // Bit fields.
  SetFieldValues(*this, kernel_info.get(), &GetIndexedBitFieldString,
                 &BooleanToValue, BIT_FIELDS_BEGIN, INDEXED_BIT_FIELDS_END - 1);
  SetFieldValues(*this, kernel_info.get(), &GetIsDelFieldString,
                 &BooleanToValue, INDEXED_BIT_FIELDS_END, IS_DEL);
  SetFieldValues(*this, kernel_info.get(), &GetBitFieldString, &BooleanToValue,
                 IS_DEL + 1, BIT_FIELDS_END - 1);

  // String fields.
  {
    // Pick out the function overload we want.
    SetFieldValues(*this, kernel_info.get(), &GetStringFieldString,
                   &StringToValue, STRING_FIELDS_BEGIN, STRING_FIELDS_END - 1);
  }

  // Proto fields.
  SetEncryptableProtoValues(*this, cryptographer, kernel_info.get(),
                            PROTO_FIELDS_BEGIN, PROTO_FIELDS_END - 1);

  // UniquePosition fields
  SetFieldValues(*this, kernel_info.get(), &GetUniquePositionFieldString,
                 &UniquePositionToValue, UNIQUE_POSITION_FIELDS_BEGIN,
                 UNIQUE_POSITION_FIELDS_END - 1);

  // Bit temps.
  SetFieldValues(*this, kernel_info.get(), &GetBitTempString, &BooleanToValue,
                 BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1);

  return kernel_info;
}

size_t EntryKernel::EstimateMemoryUsage() const {
  if (memory_usage_ == kMemoryUsageUnknown) {
    using base::trace_event::EstimateMemoryUsage;
    memory_usage_ = EstimateMemoryUsage(string_fields) +
                    EstimateSharedMemoryUsage(specifics_fields) +
                    EstimateMemoryUsage(id_fields) +
                    EstimateMemoryUsage(unique_position_fields);
  }
  return memory_usage_;
}

std::unique_ptr<base::ListValue> EntryKernelMutationMapToValue(
    const EntryKernelMutationMap& mutations) {
  std::unique_ptr<base::ListValue> list(new base::ListValue());
  for (auto it = mutations.begin(); it != mutations.end(); ++it) {
    list->Append(EntryKernelMutationToValue(it->second));
  }
  return list;
}

std::unique_ptr<base::DictionaryValue> EntryKernelMutationToValue(
    const EntryKernelMutation& mutation) {
  auto dict = std::make_unique<base::DictionaryValue>();
  dict->Set("original", mutation.original.ToValue(nullptr));
  dict->Set("mutated", mutation.mutated.ToValue(nullptr));
  return dict;
}

std::ostream& operator<<(std::ostream& os, const EntryKernel& entry_kernel) {
  int i;
  EntryKernel* const kernel = const_cast<EntryKernel*>(&entry_kernel);
  for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) {
    os << g_metas_columns[i].name << ": "
       << kernel->ref(static_cast<Int64Field>(i)) << ", ";
  }
  for (; i < TIME_FIELDS_END; ++i) {
    os << g_metas_columns[i].name << ": "
       << GetTimeDebugString(kernel->ref(static_cast<TimeField>(i))) << ", ";
  }
  for (; i < ID_FIELDS_END; ++i) {
    os << g_metas_columns[i].name << ": "
       << kernel->ref(static_cast<IdField>(i)) << ", ";
  }
  os << "Flags: ";
  for (; i < BIT_FIELDS_END; ++i) {
    if (kernel->ref(static_cast<BitField>(i)))
      os << g_metas_columns[i].name << ", ";
  }
  for (; i < STRING_FIELDS_END; ++i) {
    const std::string& field = kernel->ref(static_cast<StringField>(i));
    os << g_metas_columns[i].name << ": " << field << ", ";
  }
  for (; i < PROTO_FIELDS_END; ++i) {
    std::string escaped_str = base::EscapeBytesAsInvalidJSONString(
        kernel->ref(static_cast<ProtoField>(i)).SerializeAsString(), false);
    os << g_metas_columns[i].name << ": " << escaped_str << ", ";
  }
  for (; i < UNIQUE_POSITION_FIELDS_END; ++i) {
    os << g_metas_columns[i].name << ": "
       << kernel->ref(static_cast<UniquePositionField>(i)).ToDebugString()
       << ", ";
  }
  os << "TempFlags: ";
  for (; i < BIT_TEMPS_END; ++i) {
    if (kernel->ref(static_cast<BitTemp>(i)))
      os << "#" << i - BIT_TEMPS_BEGIN << ", ";
  }
  return os;
}

}  // namespace syncable
}  // namespace syncer
