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

#include "base/json/json_string_value_serializer.h"

namespace syncer {

// static
ObjectIdInvalidationMap ObjectIdInvalidationMap::InvalidateAll(
    const ObjectIdSet& ids) {
  ObjectIdInvalidationMap invalidate_all;
  for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
    invalidate_all.Insert(Invalidation::InitUnknownVersion(*it));
  }
  return invalidate_all;
}

ObjectIdInvalidationMap::ObjectIdInvalidationMap() {}

ObjectIdInvalidationMap::~ObjectIdInvalidationMap() {}

ObjectIdSet ObjectIdInvalidationMap::GetObjectIds() const {
  ObjectIdSet ret;
  for (IdToListMap::const_iterator it = map_.begin(); it != map_.end(); ++it) {
    ret.insert(it->first);
  }
  return ret;
}

bool ObjectIdInvalidationMap::Empty() const {
  return map_.empty();
}

void ObjectIdInvalidationMap::Insert(const Invalidation& invalidation) {
  map_[invalidation.object_id()].Insert(invalidation);
}

ObjectIdInvalidationMap ObjectIdInvalidationMap::GetSubsetWithObjectIds(
    const ObjectIdSet& ids) const {
  IdToListMap new_map;
  for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
    IdToListMap::const_iterator lookup = map_.find(*it);
    if (lookup != map_.end()) {
      new_map[*it] = lookup->second;
    }
  }
  return ObjectIdInvalidationMap(new_map);
}

const SingleObjectInvalidationSet& ObjectIdInvalidationMap::ForObject(
    invalidation::ObjectId id) const {
  IdToListMap::const_iterator lookup = map_.find(id);
  DCHECK(lookup != map_.end());
  DCHECK(!lookup->second.IsEmpty());
  return lookup->second;
}

void ObjectIdInvalidationMap::GetAllInvalidations(
    std::vector<syncer::Invalidation>* out) const {
  for (IdToListMap::const_iterator it = map_.begin(); it != map_.end(); ++it) {
    out->insert(out->begin(), it->second.begin(), it->second.end());
  }
}
void ObjectIdInvalidationMap::AcknowledgeAll() const {
  for (IdToListMap::const_iterator it1 = map_.begin();
       it1 != map_.end(); ++it1) {
    for (SingleObjectInvalidationSet::const_iterator it2 = it1->second.begin();
         it2 != it1->second.end(); ++it2) {
      it2->Acknowledge();
    }
  }
}

bool ObjectIdInvalidationMap::operator==(
    const ObjectIdInvalidationMap& other) const {
  return map_ == other.map_;
}

scoped_ptr<base::ListValue> ObjectIdInvalidationMap::ToValue() const {
  scoped_ptr<base::ListValue> value(new base::ListValue());
  for (IdToListMap::const_iterator it1 = map_.begin();
       it1 != map_.end(); ++it1) {
    for (SingleObjectInvalidationSet::const_iterator it2 =
         it1->second.begin(); it2 != it1->second.end(); ++it2) {
      value->Append(it2->ToValue().release());
    }
  }
  return value.Pass();
}

bool ObjectIdInvalidationMap::ResetFromValue(const base::ListValue& value) {
  map_.clear();
  for (size_t i = 0; i < value.GetSize(); ++i) {
    const base::DictionaryValue* dict;
    if (!value.GetDictionary(i, &dict)) {
      return false;
    }
    scoped_ptr<Invalidation> invalidation = Invalidation::InitFromValue(*dict);
    if (!invalidation) {
      return false;
    }
    Insert(*invalidation.get());
  }
  return true;
}

std::string ObjectIdInvalidationMap::ToString() const {
  std::string output;
  JSONStringValueSerializer serializer(&output);
  serializer.set_pretty_print(true);
  serializer.Serialize(*ToValue().get());
  return output;
}

ObjectIdInvalidationMap::ObjectIdInvalidationMap(const IdToListMap& map)
  : map_(map) {}

}  // namespace syncer
