/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
 *         Chaoyi Bian <bcy@pku.edu.cn>
 *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#ifndef SYNC_CCNX_WRAPPER_H
#define SYNC_CCNX_WRAPPER_H

extern "C" {
#include <ccn/ccn.h>
#include <ccn/charbuf.h>
#include <ccn/keystore.h>
#include <ccn/uri.h>
#include <ccn/bloom.h>
#include <ccn/signing.h>
}

#include <boost/exception/all.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include <string>
#include <sstream>
#include <map>

/**
 * \defgroup sync SYNC protocol
 *
 * Implementation of SYNC protocol
 */
namespace Sync {

struct CcnxOperationException : virtual boost::exception, virtual std::exception { };
/**
 * \ingroup sync
 * @brief A wrapper for ccnx library; clients of this code do not need to deal
 * with ccnx library
 */
class CcnxWrapper {
public:
  typedef boost::function<void (std::string, std::string)> StringDataCallback;
  typedef boost::function<void (std::string, const char *buf, size_t len)> RawDataCallback;
  typedef boost::function<void (std::string)> InterestCallback;

private:
  static boost::shared_ptr<CcnxWrapper> s_wrapper;

public:
  static
  boost::shared_ptr<CcnxWrapper>
  Create ()
  {
    if (s_wrapper.get () == 0)
      s_wrapper = boost::shared_ptr<CcnxWrapper> (new CcnxWrapper ());
    
    return s_wrapper;
  }

  static
  void
  Destroy ()
  {
    s_wrapper.reset ();
  }
  
private:
  /**
   * @brief initialize the wrapper; a lot of things needs to be done. 1) init
   * keystore 2) init keylocator 3) start a thread to hold a loop of ccn_run
   *
   */
#ifdef _DEBUG_WRAPPER_      
  CcnxWrapper(char c='.');
  char m_c;
#else
  CcnxWrapper();
#endif

public:  
  ~CcnxWrapper();

  /**
   * @brief send Interest; need to grab lock m_mutex first
   *
   * @param strInterest the Interest name
   * @param dataCallback the callback function to deal with the returned data
   * @return the return code of ccn_express_interest
   */
  int
  sendInterestForString (const std::string &strInterest, const StringDataCallback &strDataCallback, int retry = 0);

  int 
  sendInterest (const std::string &strInterest, const RawDataCallback &rawDataCallback, int retry = 0);

  /**
   * @brief set Interest filter (specify what interest you want to receive)
   *
   * @param prefix the prefix of Interest
   * @param interestCallback the callback function to deal with the returned data
   * @return the return code of ccn_set_interest_filter
   */
  int
  setInterestFilter (const std::string &prefix, const InterestCallback &interestCallback);

  /**
   * @brief clear Interest filter
   * @param prefix the prefix of Interest
   */
  void
  clearInterestFilter (const std::string &prefix);

  /**
   * @brief publish data and put it to local ccn content store; need to grab
   * lock m_mutex first
   *
   * @param name the name for the data object
   * @param dataBuffer the data to be published
   * @param freshness the freshness time for the data object
   * @return code generated by ccnx library calls, >0 if success
   */
  int
  publishStringData (const std::string &name, const std::string &dataBuffer, int freshness);

  int 
  publishRawData (const std::string &name, const char *buf, size_t len, int freshness);

  std::string
  getLocalPrefix ();
  
private:
  void
  connectCcnd();

  /// @cond include_hidden 
  void
  createKeyLocator ();

  void
  initKeyStore ();

  const ccn_pkey *
  getPrivateKey ();

  const unsigned char *
  getPublicKeyDigest ();

  ssize_t
  getPublicKeyDigestLength ();

  void
  ccnLoop ();

  int 
  sendInterest (const std::string &strInterest, void *dataPass);
  /// @endcond
private:
  ccn* m_handle;
  ccn_keystore *m_keyStore;
  ccn_charbuf *m_keyLoactor;
  // to lock, use "boost::recursive_mutex::scoped_lock scoped_lock(mutex);
  boost::recursive_mutex m_mutex;
  boost::thread m_thread;
  bool m_running;
  bool m_connected;
  std::map<std::string, InterestCallback> m_registeredInterests;
  // std::list< std::pair<std::string, InterestCallback> > m_registeredInterests;
};

typedef boost::shared_ptr<CcnxWrapper> CcnxWrapperPtr;

enum CallbackType { STRING_FORM, RAW_DATA};

class ClosurePass {
public:
  ClosurePass(CallbackType type, int retry): m_retry(retry), m_type(type) {}
  int getRetry() {return m_retry;}
  void decRetry() { m_retry--;}
  CallbackType getCallbackType() {return m_type;}
  virtual ~ClosurePass(){}
  virtual void runCallback(std::string name, const char *data, size_t len) = 0;

protected:
  int m_retry;
  CallbackType m_type;
};

class DataClosurePass: public ClosurePass {
public:
  DataClosurePass(CallbackType type, int retry, const CcnxWrapper::StringDataCallback &strDataCallback);
  virtual ~DataClosurePass();
  virtual void runCallback(std::string name, const char *, size_t len);
private:
  CcnxWrapper::StringDataCallback * m_callback;  
};

class RawDataClosurePass: public ClosurePass {
public:
  RawDataClosurePass(CallbackType type, int retry, const CcnxWrapper::RawDataCallback &RawDataCallback);
  virtual ~RawDataClosurePass();
  virtual void runCallback(std::string name, const char *, size_t len);
private:
  CcnxWrapper::RawDataCallback * m_callback;  
};

} // Sync

#endif // SYNC_CCNX_WRAPPER_H
