/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012-2017 University of California, Los Angeles
 *
 * This file is part of ChronoSync, synchronization library for distributed realtime
 * applications for NDN.
 *
 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
 * @author Chaoyi Bian <bcy@pku.edu.cn>
 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
 * @author Yingdi Yu <yingdi@cs.ucla.edu>
 */

#include "state.hpp"

namespace chronosync {

using boost::make_tuple;

State::~State()
{
}

/**
 * @brief Add or update leaf to the sync tree
 *
 * @param info session name of the leaf
 * @param seq  sequence number of the leaf
 * @return 3-tuple (isInserted, isUpdated, oldSeqNo)
 */
boost::tuple<bool, bool, SeqNo>
State::update(const Name& info, const SeqNo& seq)
{
  m_wire.reset();

  LeafContainer::iterator leaf = m_leaves.find(info);

  if (leaf == m_leaves.end()) {
    m_leaves.insert(make_shared<Leaf>(info, cref(seq)));
    return make_tuple(true, false, 0);
  }
  else {
    if ((*leaf)->getSeq() == seq || seq < (*leaf)->getSeq()) {
      return make_tuple(false, false, 0);
    }

    SeqNo old = (*leaf)->getSeq();
    m_leaves.modify(leaf,
                    [=] (LeafPtr& leaf) { leaf->setSeq(seq); } );
    return make_tuple(false, true, old);
  }
}

ndn::ConstBufferPtr
State::getRootDigest() const
{
  m_digest.reset();

  BOOST_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
    {
      BOOST_ASSERT(leaf != 0);
      m_digest.update(leaf->getDigest()->buf(), leaf->getDigest()->size());
    }

  return m_digest.computeDigest();
}


void
State::reset()
{
  m_leaves.clear();
}

State&
State::operator+=(const State& state)
{
  BOOST_FOREACH (ConstLeafPtr leaf, state.getLeaves())
    {
      BOOST_ASSERT(leaf != 0);
      update(leaf->getSessionName(), leaf->getSeq());
    }

  return *this;
}

template<bool T>
size_t
State::wireEncode(ndn::EncodingImpl<T>& block) const
{
  size_t totalLength = 0;

  BOOST_REVERSE_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
    {
      size_t entryLength = 0;
      entryLength += prependNonNegativeIntegerBlock(block, tlv::SeqNo, leaf->getSeq());
      entryLength += leaf->getSessionName().wireEncode(block);
      entryLength += block.prependVarNumber(entryLength);
      entryLength += block.prependVarNumber(tlv::StateLeaf);
      totalLength += entryLength;
    }

  totalLength += block.prependVarNumber(totalLength);
  totalLength += block.prependVarNumber(tlv::SyncReply);

  return totalLength;
}

//! \relates State
template size_t
State::wireEncode<true>(ndn::EncodingImpl<true>& block) const;

//! \relates State
template size_t
State::wireEncode<false>(ndn::EncodingImpl<false>& block) const;

const Block&
State::wireEncode() const
{
  if (m_wire.hasWire())
    return m_wire;

  ndn::EncodingEstimator estimator;
  size_t estimatedSize = wireEncode(estimator);

  ndn::EncodingBuffer buffer(estimatedSize, 0);
  wireEncode(buffer);

  m_wire = buffer.block();
  return m_wire;
}

void
State::wireDecode(const Block& wire)
{
  if (!wire.hasWire())
    BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));

  if (wire.type() != tlv::SyncReply)
    BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding SyncReply: " +
                                boost::lexical_cast<std::string>(m_wire.type())));

  wire.parse();
  m_wire = wire;

  for (Block::element_const_iterator it = wire.elements_begin();
       it != wire.elements_end(); it++) {
    if (it->type() == tlv::StateLeaf) {
      it->parse();

      Block::element_const_iterator val = it->elements_begin();
      Name info(*val);
      val++;

      if (val != it->elements_end())
        update(info, readNonNegativeInteger(*val));
      else
        BOOST_THROW_EXCEPTION(Error("No seqNo when decoding SyncReply"));
    }
  }
}

} // namespace chronosync
