/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012-2014 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 <http://irl.cs.ucla.edu/~yingdi/web/index.html>
 */

#ifndef SYNC_LOGIC_H
#define SYNC_LOGIC_H

#include <boost/random.hpp>
#include <memory>
#include <map>

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/scheduler.hpp>

#include "sync-interest-table.h"
#include "sync-diff-state.h"
#include "sync-full-state.h"
#include "sync-std-name-info.h"

#include "sync-diff-state-container.h"

#ifdef _DEBUG
#ifdef HAVE_LOG4CXX
#include <log4cxx/logger.h>
#endif
#endif

namespace Sync {

struct MissingDataInfo {
  std::string prefix;
  SeqNo low;
  SeqNo high;
};

/**
 * \ingroup sync
 * @brief A wrapper for SyncApp, which handles ccnx related things (process
 * interests and data)
 */

class SyncLogic
{
public:
  //typedef boost::function< void ( const std::string &/*prefix*/, const SeqNo &/*newSeq*/, const SeqNo &/*oldSeq*/ ) > LogicUpdateCallback;
  typedef boost::function< void (const std::vector<MissingDataInfo> & ) > LogicUpdateCallback;
  typedef boost::function< void (const std::string &/*prefix*/ ) > LogicRemoveCallback;
  typedef boost::function< void (const std::string &)> LogicPerBranchCallback;

  SyncLogic (const ndn::Name& syncPrefix,
             const ndn::IdentityCertificate& myCertificate,
             ndn::shared_ptr<ndn::Validator> validator,
             ndn::shared_ptr<ndn::Face> face,
             LogicUpdateCallback onUpdate,
             LogicRemoveCallback onRemove);

  SyncLogic (const ndn::Name& syncPrefix,
             const ndn::IdentityCertificate& myCertificate,
             ndn::shared_ptr<ndn::Validator> validator,
             ndn::shared_ptr<ndn::Face> face,
             LogicPerBranchCallback onUpdateBranch);

  ~SyncLogic ();

  /**
   * a wrapper for the same func in SyncApp
   */
  void addLocalNames (const ndn::Name &prefix, uint64_t session, uint64_t seq);

  /**
   * @brief remove a participant's subtree from the sync tree
   * @param prefix the name prefix for the participant
   */
  void remove (const ndn::Name &prefix);

  std::string
  getRootDigest();

#ifdef _DEBUG
  ndn::Scheduler &
  getScheduler () { return m_scheduler; }
#endif

  void
  printState () const;

  std::map<std::string, bool>
  getBranchPrefixes() const;

private:
  void
  delayedChecksLoop ();

  void
  onSyncInterest (const ndn::Name& prefix, const ndn::Interest& interest);

  void
  onSyncRegisterFailed(const ndn::Name& prefix, const std::string& msg);

  void
  onSyncData(const ndn::Interest& interest, ndn::Data& data);

  void
  onSyncTimeout(const ndn::Interest& interest);

  void
  onSyncDataValidationFailed(const ndn::shared_ptr<const ndn::Data>& data);

  void
  onSyncDataValidated(const ndn::shared_ptr<const ndn::Data>& data);

  void
  processSyncInterest (const ndn::Name &name,
                       DigestConstPtr digest, bool timedProcessing=false);

  void
  processSyncData (const ndn::Name &name,
                   DigestConstPtr digest, const char *wireData, size_t len);

  void
  processSyncRecoveryInterest (const ndn::Name &name,
                               DigestConstPtr digest);

  void
  insertToDiffLog (DiffStatePtr diff);

  void
  satisfyPendingSyncInterests (DiffStateConstPtr diff);

  boost::tuple<DigestConstPtr, std::string>
  convertNameToDigestAndType (const ndn::Name &name);

  void
  sendSyncInterest ();

  void
  sendSyncRecoveryInterests (DigestConstPtr digest);

  void
  sendSyncData (const ndn::Name &name,
                DigestConstPtr digest, StateConstPtr state);

  void
  sendSyncData (const ndn::Name &name,
                DigestConstPtr digest, SyncStateMsg &msg);

  size_t
  getNumberOfBranches () const;

private:
  FullStatePtr m_state;
  DiffStateContainer m_log;

  ndn::Name m_outstandingInterestName;
  SyncInterestTable m_syncInterestTable;

  ndn::Name m_syncPrefix;
  ndn::IdentityCertificate m_myCertificate;
  LogicUpdateCallback m_onUpdate;
  LogicRemoveCallback m_onRemove;
  LogicPerBranchCallback m_onUpdateBranch;
  bool m_perBranch;
  ndn::shared_ptr<ndn::Validator> m_validator;
  ndn::KeyChain m_keyChain;
  ndn::shared_ptr<ndn::Face> m_face;
  const ndn::RegisteredPrefixId* m_syncRegisteredPrefixId;

  ndn::Scheduler m_scheduler;

  boost::mt19937 m_randomGenerator;
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_rangeUniformRandom;
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > m_reexpressionJitter;

  static const int m_unknownDigestStoreTime = 10; // seconds
  static const int m_syncResponseFreshness; // MUST BE dividable by 1000!!!
  static const int m_syncInterestReexpress; // seconds

  static const int m_defaultRecoveryRetransmitInterval = 200; // milliseconds
  uint32_t m_recoveryRetransmissionInterval; // milliseconds

  ndn::EventId m_delayedInterestProcessingId;
  ndn::EventId m_reexpressingInterestId;
  ndn::EventId m_reexpressingRecoveryInterestId;

  std::string m_instanceId;
  static int m_instanceCounter;
};


} // Sync

#endif // SYNC_APP_WRAPPER_H
