/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2014 University of Arizona.
 *
 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 */

#include <boost/utility.hpp>
 
#include <ndn-cpp-dev/face.hpp>
#include <ndn-cpp-dev/security/key-chain.hpp>

namespace ndntlvpoke {

class NdnTlvPoke : boost::noncopyable
{

public:

  explicit
  NdnTlvPoke(char* programName)
    : m_programName(programName)
    , m_isForceDataSet(false)
    , m_isUseDigestSha256Set(false)
    , m_isLastAsFinalBlockIdSet(false)
    , m_freshnessPeriod(-1)
    , m_timeout(-1)
    , m_isDataSent(false)
  {
  }

  void
  usage()
  {
    std::cout << "\n Usage:\n " << m_programName << " "
      "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
      "   Reads payload from stdin and sends it to local NDN forwarder as a "
      "single Data packet\n"
      "   [-f]          - force, send Data without waiting for Interest\n"
      "   [-D]          - use DigestSha256 signing method instead of "
      "SignatureSha256WithRsa\n"
      "   [-i identity] - set identity to be used for signing\n"
      "   [-F]          - set FinalBlockId to the last component of Name\n"
      "   [-x]          - set FreshnessPeriod in time::milliseconds\n"
      "   [-w timeout]  - set Timeout in time::milliseconds\n"
      "   [-h]          - print help and exit\n\n";
    exit(1);
  }

  void
  setForceData()
  {
    m_isForceDataSet = true;
  }

  void
  setUseDigestSha256()
  {
    m_isUseDigestSha256Set = true;
  }

  void
  setIdentityName(char* identityName)
  {
    m_identityName = ndn::make_shared<ndn::Name>(identityName);
  }

  void
  setLastAsFinalBlockId()
  {
    m_isLastAsFinalBlockIdSet = true;
  }

  void
  setFreshnessPeriod(int freshnessPeriod)
  {
    if (freshnessPeriod < 0)
      usage();
    m_freshnessPeriod = ndn::time::milliseconds(freshnessPeriod);
  }

  void
  setTimeout(int timeout)
  {
    if (timeout < 0)
      usage();
    m_timeout = ndn::time::milliseconds(timeout);
  }

  void
  setPrefixName(char* prefixName)
  {
    m_prefixName = ndn::Name(prefixName);
  }

  ndn::time::milliseconds
  getDefaultTimeout()
  {
    return ndn::time::seconds(10);
  }

  ndn::Data
  createDataPacket()
  {
    ndn::Data dataPacket(m_prefixName);
    std::stringstream payloadStream;
    payloadStream << std::cin.rdbuf();
    std::string payload = payloadStream.str();
    dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
    if (m_freshnessPeriod >= ndn::time::milliseconds::zero())
      dataPacket.setFreshnessPeriod(m_freshnessPeriod);
    if (m_isLastAsFinalBlockIdSet)
      {
        if (!m_prefixName.empty())
          dataPacket.setFinalBlockId(m_prefixName.get(-1));
        else
          {
            std::cerr << "Name Provided Has 0 Components" << std::endl;
            exit(1);
          }
      }
    if (m_isUseDigestSha256Set)
      m_keyChain.signWithSha256(dataPacket);
    else
      {
        if (!static_cast<bool>(m_identityName))
          m_keyChain.sign(dataPacket);
        else
          m_keyChain.signByIdentity(dataPacket, *m_identityName);
      }
    return dataPacket;
  }

  void
  onInterest(const ndn::Name& name,
             const ndn::Interest& interest,
             const ndn::Data& dataPacket)
  {
    m_face.put(dataPacket);
    m_isDataSent = true;
    m_face.shutdown();
  }

  void
  onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
  {
    std::cerr << "Prefix Registration Failure." << std::endl;
    std::cerr << "Reason = " << reason << std::endl;
  }

  void
  run()
  {
    try
      {
        ndn::Data dataPacket = createDataPacket();
        if (m_isForceDataSet)
          {
            m_face.put(dataPacket);
            m_isDataSent = true;
          }
        else
          {
            m_face.setInterestFilter(m_prefixName,
                                     ndn::bind(&NdnTlvPoke::onInterest,
                                               this, _1, _2, dataPacket),
                                     ndn::bind(&NdnTlvPoke::onRegisterFailed,
                                               this, _1, _2));
          }
        if (m_timeout < ndn::time::milliseconds::zero())
          m_face.processEvents(getDefaultTimeout());
        else
          m_face.processEvents(m_timeout);
      }
    catch (std::exception& e)
      {
        std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
        exit(1);
      }
  }

  bool
  isDataSent() const
  {
    return m_isDataSent;
  }

private:

  ndn::KeyChain m_keyChain;
  std::string m_programName;
  bool m_isForceDataSet;
  bool m_isUseDigestSha256Set;
  ndn::shared_ptr<ndn::Name> m_identityName;
  bool m_isLastAsFinalBlockIdSet;
  ndn::time::milliseconds m_freshnessPeriod;
  ndn::time::milliseconds m_timeout;
  ndn::Name m_prefixName;
  bool m_isDataSent;
  ndn::Face m_face;

};

}

int
main(int argc, char* argv[])
{
  int option;
  ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]);
  while ((option = getopt(argc, argv, "hfDi:Fx:w:")) != -1)
    {
      switch (option) {
        case 'h':
          ndnTlvPoke.usage();
          break;
        case 'f':
          ndnTlvPoke.setForceData();
          break;
        case 'D':
          ndnTlvPoke.setUseDigestSha256();
          break;
        case 'i':
          ndnTlvPoke.setIdentityName(optarg);
          break;
        case 'F':
          ndnTlvPoke.setLastAsFinalBlockId();
          break;
        case 'x':
          ndnTlvPoke.setFreshnessPeriod(atoi(optarg));
          break;
        case 'w':
          ndnTlvPoke.setTimeout(atoi(optarg));
          break;
        default:
          ndnTlvPoke.usage();
          break;
      }
    }

  argc -= optind;
  argv += optind;

  if (argv[0] == 0)
    ndnTlvPoke.usage();

  ndnTlvPoke.setPrefixName(argv[0]);
  ndnTlvPoke.run();

  if (ndnTlvPoke.isDataSent())
    return 0;
  else
    return 1;
}
