// Copyright 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 "sync/internal_api/change_reorder_buffer.h"

#include <limits>
#include <queue>
#include <set>
#include <utility>  // for pair<>

#include "sync/internal_api/public/base_node.h"
#include "sync/internal_api/public/base_transaction.h"
#include "sync/syncable/entry.h"
#include "sync/syncable/syncable_base_transaction.h"

using std::numeric_limits;
using std::pair;
using std::queue;
using std::set;

namespace syncer {

// Traversal provides a way to collect a set of nodes from the syncable
// directory structure and then traverse them, along with any intermediate
// nodes, in a top-down fashion, starting from a single common ancestor.  A
// Traversal starts out empty and is grown by means of the ExpandToInclude
// method.  Once constructed, the top(), begin_children(), and end_children()
// methods can be used to explore the nodes in root-to-leaf order.
class ChangeReorderBuffer::Traversal {
 public:
  typedef pair<int64, int64> ParentChildLink;
  typedef set<ParentChildLink> LinkSet;

  Traversal() : top_(kInvalidId) { }

  // Expand the traversal so that it includes the node indicated by
  // |child_handle|.
  void ExpandToInclude(syncable::BaseTransaction* trans,
                       int64 child_handle) {
    // If |top_| is invalid, this is the first insertion -- easy.
    if (top_ == kInvalidId) {
      top_ = child_handle;
      return;
    }

    int64 node_to_include = child_handle;
    while (node_to_include != kInvalidId && node_to_include != top_) {
      int64 node_parent = 0;

      syncable::Entry node(trans, syncable::GET_BY_HANDLE, node_to_include);
      CHECK(node.good());
      if (node.GetId().IsRoot()) {
        // If we've hit the root, and the root isn't already in the tree
        // (it would have to be |top_| if it were), start a new expansion
        // upwards from |top_| to unite the original traversal with the
        // path we just added that goes from |child_handle| to the root.
        node_to_include = top_;
        top_ = node.GetMetahandle();
      } else {
        // Otherwise, get the parent ID so that we can add a ParentChildLink.
        syncable::Entry parent(trans, syncable::GET_BY_ID,
                               node.GetParentId());
        CHECK(parent.good());
        node_parent = parent.GetMetahandle();

        ParentChildLink link(node_parent, node_to_include);

        // If the link exists in the LinkSet |links_|, we don't need to search
        // any higher; we are done.
        if (links_.find(link) != links_.end())
          return;

        // Otherwise, extend |links_|, and repeat on the parent.
        links_.insert(link);
        node_to_include = node_parent;
      }
    }
  }

  // Return the top node of the traversal.  Use this as a starting point
  // for walking the tree.
  int64 top() const { return top_; }

  // Return an iterator corresponding to the first child (in the traversal)
  // of the node specified by |parent_id|.  Iterate this return value until
  // it is equal to the value returned by end_children(parent_id).  The
  // enumeration thus provided is unordered.
  LinkSet::const_iterator begin_children(int64 parent_id) const {
    return links_.upper_bound(
        ParentChildLink(parent_id, numeric_limits<int64>::min()));
  }

  // Return an iterator corresponding to the last child in the traversal
  // of the node specified by |parent_id|.
  LinkSet::const_iterator end_children(int64 parent_id) const {
    return begin_children(parent_id + 1);
  }

 private:
  // The topmost point in the directory hierarchy that is in the traversal,
  // and thus the first node to be traversed.  If the traversal is empty,
  // this is kInvalidId.  If the traversal contains exactly one member, |top_|
  // will be the solitary member, and |links_| will be empty.
  int64 top_;
  // A set of single-level links that compose the traversal below |top_|.  The
  // (parent, child) ordering of values enables efficient lookup of children
  // given the parent handle, which is used for top-down traversal.  |links_|
  // is expected to be connected -- every node that appears as a parent in a
  // link must either appear as a child of another link, or else be the
  // topmost node, |top_|.
  LinkSet links_;

  DISALLOW_COPY_AND_ASSIGN(Traversal);
};

ChangeReorderBuffer::ChangeReorderBuffer() {
}

ChangeReorderBuffer::~ChangeReorderBuffer() {
}

void ChangeReorderBuffer::PushAddedItem(int64 id) {
  operations_[id] = ChangeRecord::ACTION_ADD;
}

void ChangeReorderBuffer::PushDeletedItem(int64 id) {
  operations_[id] = ChangeRecord::ACTION_DELETE;
}

void ChangeReorderBuffer::PushUpdatedItem(int64 id) {
  operations_[id] = ChangeRecord::ACTION_UPDATE;
}

void ChangeReorderBuffer::SetExtraDataForId(
    int64 id,
    ExtraPasswordChangeRecordData* extra) {
  extra_data_[id] = make_linked_ptr<ExtraPasswordChangeRecordData>(extra);
}

void ChangeReorderBuffer::SetSpecificsForId(
    int64 id,
    const sync_pb::EntitySpecifics& specifics) {
  specifics_[id] = specifics;
}

void ChangeReorderBuffer::Clear() {
  operations_.clear();
}

bool ChangeReorderBuffer::IsEmpty() const {
  return operations_.empty();
}

bool ChangeReorderBuffer::GetAllChangesInTreeOrder(
    const BaseTransaction* sync_trans,
    ImmutableChangeRecordList* changes) {
  syncable::BaseTransaction* trans = sync_trans->GetWrappedTrans();

  // Step 1: Iterate through the operations, doing three things:
  // (a) Push deleted items straight into the |changelist|.
  // (b) Construct a traversal spanning all non-deleted items.
  // (c) Construct a set of all parent nodes of any position changes.
  Traversal traversal;

  ChangeRecordList changelist;

  OperationMap::const_iterator i;
  for (i = operations_.begin(); i != operations_.end(); ++i) {
    if (i->second == ChangeRecord::ACTION_DELETE) {
      ChangeRecord record;
      record.id = i->first;
      record.action = i->second;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist.push_back(record);
    } else {
      traversal.ExpandToInclude(trans, i->first);
    }
  }

  // Step 2: Breadth-first expansion of the traversal.
  queue<int64> to_visit;
  to_visit.push(traversal.top());
  while (!to_visit.empty()) {
    int64 next = to_visit.front();
    to_visit.pop();

    // If the node has an associated action, output a change record.
    i = operations_.find(next);
    if (i != operations_.end()) {
      ChangeRecord record;
      record.id = next;
      record.action = i->second;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist.push_back(record);
    }

    // Now add the children of |next| to |to_visit|.
    Traversal::LinkSet::const_iterator j = traversal.begin_children(next);
    Traversal::LinkSet::const_iterator end = traversal.end_children(next);
    for (; j != end; ++j) {
      CHECK(j->first == next);
      to_visit.push(j->second);
    }
  }

  *changes = ImmutableChangeRecordList(&changelist);
  return true;
}

}  // namespace syncer
