// Copyright 2014 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/invalidation/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
