// 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/nigori/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::NumberToString(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
