// Copyright 2013 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 "sync/notifier/unacked_invalidation_set.h"

#include "base/strings/string_number_conversions.h"
#include "sync/internal_api/public/base/ack_handle.h"
#include "sync/notifier/object_id_invalidation_map.h"

namespace {

const char kSourceKey[] = "source";
const char kNameKey[] = "name";
const char kInvalidationListKey[] = "invalidation-list";

}  // namespace

namespace syncer {

const size_t UnackedInvalidationSet::kMaxBufferedInvalidations = 5;

// static
UnackedInvalidationSet::UnackedInvalidationSet(
    invalidation::ObjectId id)
    : registered_(false),
      object_id_(id) {}

UnackedInvalidationSet::UnackedInvalidationSet(
    const UnackedInvalidationSet& other)
    : registered_(other.registered_),
      object_id_(other.object_id_),
      invalidations_(other.invalidations_) {
}

UnackedInvalidationSet::~UnackedInvalidationSet() {}

const invalidation::ObjectId& UnackedInvalidationSet::object_id() const {
  return object_id_;
}

void UnackedInvalidationSet::Add(
    const Invalidation& invalidation) {
  SingleObjectInvalidationSet set;
  set.Insert(invalidation);
  AddSet(set);
  if (!registered_)
    Truncate(kMaxBufferedInvalidations);
}

void UnackedInvalidationSet::AddSet(
    const SingleObjectInvalidationSet& invalidations) {
  invalidations_.insert(invalidations.begin(), invalidations.end());
  if (!registered_)
    Truncate(kMaxBufferedInvalidations);
}

void UnackedInvalidationSet::ExportInvalidations(
    WeakHandle<AckHandler> ack_handler,
    ObjectIdInvalidationMap* out) const {
  for (SingleObjectInvalidationSet::const_iterator it = invalidations_.begin();
       it != invalidations_.end(); ++it) {
    // Copy the invalidation and set the copy's ack_handler.
    Invalidation inv(*it);
    inv.set_ack_handler(ack_handler);
    out->Insert(inv);
  }
}

void UnackedInvalidationSet::Clear() {
  invalidations_.clear();
}

void UnackedInvalidationSet::SetHandlerIsRegistered() {
  registered_ = true;
}

void UnackedInvalidationSet::SetHandlerIsUnregistered() {
  registered_ = false;
  Truncate(kMaxBufferedInvalidations);
}

// Removes the matching ack handle from the list.
void UnackedInvalidationSet::Acknowledge(const AckHandle& handle) {
  bool handle_found = false;
  for (SingleObjectInvalidationSet::const_iterator it = invalidations_.begin();
       it != invalidations_.end(); ++it) {
    if (it->ack_handle().Equals(handle)) {
      invalidations_.erase(*it);
      handle_found = true;
      break;
    }
  }
  DLOG_IF(WARNING, !handle_found)
      << "Unrecognized to ack for object " << ObjectIdToString(object_id_);
  (void)handle_found;  // Silence unused variable warning in release builds.
}

// Erase the invalidation with matching ack handle from the list.  Also creates
// an 'UnknownVersion' invalidation with the same ack handle and places it at
// the beginning of the list.  If an unknown version invalidation currently
// exists, it is replaced.
void UnackedInvalidationSet::Drop(const AckHandle& handle) {
  SingleObjectInvalidationSet::const_iterator it;
  for (it = invalidations_.begin(); it != invalidations_.end(); ++it) {
    if (it->ack_handle().Equals(handle)) {
      break;
    }
  }
  if (it == invalidations_.end()) {
    DLOG(WARNING) << "Unrecognized drop request for object "
                  << ObjectIdToString(object_id_);
    return;
  }

  Invalidation unknown_version = Invalidation::InitFromDroppedInvalidation(*it);
  invalidations_.erase(*it);

  // If an unknown version is in the list, we remove it so we can replace it.
  if (!invalidations_.empty() && invalidations_.begin()->is_unknown_version()) {
    invalidations_.erase(*invalidations_.begin());
  }

  invalidations_.insert(unknown_version);
}

scoped_ptr<base::DictionaryValue> UnackedInvalidationSet::ToValue() const {
  scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue);
  value->SetString(kSourceKey, base::IntToString(object_id_.source()));
  value->SetString(kNameKey, object_id_.name());

  scoped_ptr<base::ListValue> list_value(new base::ListValue);
  for (InvalidationsSet::const_iterator it = invalidations_.begin();
       it != invalidations_.end(); ++it) {
    list_value->Append(it->ToValue().release());
  }
  value->Set(kInvalidationListKey, list_value.release());

  return value.Pass();
}

bool UnackedInvalidationSet::ResetFromValue(
    const base::DictionaryValue& value) {
  std::string source_str;
  if (!value.GetString(kSourceKey, &source_str)) {
    DLOG(WARNING) << "Unable to deserialize source";
    return false;
  }
  int source = 0;
  if (!base::StringToInt(source_str, &source)) {
    DLOG(WARNING) << "Invalid source: " << source_str;
    return false;
  }
  std::string name;
  if (!value.GetString(kNameKey, &name)) {
    DLOG(WARNING) << "Unable to deserialize name";
    return false;
  }
  object_id_ = invalidation::ObjectId(source, name);
  const base::ListValue* invalidation_list = NULL;
  if (!value.GetList(kInvalidationListKey, &invalidation_list)
      || !ResetListFromValue(*invalidation_list)) {
    // Earlier versions of this class did not set this field, so we don't treat
    // parsing errors here as a fatal failure.
    DLOG(WARNING) << "Unable to deserialize invalidation list.";
  }
  return true;
}

bool UnackedInvalidationSet::ResetListFromValue(
    const base::ListValue& list) {
  for (size_t i = 0; i < list.GetSize(); ++i) {
    const base::DictionaryValue* dict;
    if (!list.GetDictionary(i, &dict)) {
      DLOG(WARNING) << "Failed to get invalidation dictionary at index " << i;
      return false;
    }
    scoped_ptr<Invalidation> invalidation = Invalidation::InitFromValue(*dict);
    if (!invalidation) {
      DLOG(WARNING) << "Failed to parse invalidation at index " << i;
      return false;
    }
    invalidations_.insert(*invalidation.get());
  }
  return true;
}

void UnackedInvalidationSet::Truncate(size_t max_size) {
  DCHECK_GT(max_size, 0U);

  if (invalidations_.size() <= max_size) {
    return;
  }

  while (invalidations_.size() > max_size) {
    invalidations_.erase(*invalidations_.begin());
  }

  // We dropped some invalidations.  We remember the fact that an unknown
  // amount of information has been lost by ensuring this list begins with
  // an UnknownVersion invalidation.  We remove the oldest remaining
  // invalidation to make room for it.
  invalidation::ObjectId id = invalidations_.begin()->object_id();
  invalidations_.erase(*invalidations_.begin());

  Invalidation unknown_version = Invalidation::InitUnknownVersion(id);
  invalidations_.insert(unknown_version);
}

}  // namespace syncer
