/* -*- 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;


  static
  CcnxWrapper *
  Create ()
  {
    static CcnxWrapper *wrapper = new CcnxWrapper ();
    return wrapper;
  }
  
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);

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;
  std::map<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
