/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *                     Yingdi Yu
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
 */

#ifndef CHRONOS_CONTACT_MANAGER_H
#define CHRONOS_CONTACT_MANAGER_H

#include <QObject>

#ifndef Q_MOC_RUN
#include "contact-storage.h"
#include "endorse-certificate.h"
#include "profile.h"
#include "endorse-info.pb.h"
#include "endorse-collection.pb.h"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/recursive_mutex.hpp>
#endif

namespace chronos{

typedef ndn::function<void(const ndn::Interest&)> TimeoutNotify;
typedef std::vector<ndn::shared_ptr<Contact> > ContactList;

class ContactManager : public QObject
{
  Q_OBJECT

public:
  ContactManager(ndn::shared_ptr<ndn::Face> m_face,
                 QObject* parent = 0);

  ~ContactManager();

  ndn::shared_ptr<Contact>
  getContact(const ndn::Name& identity)
  {
    return m_contactStorage->getContact(identity);
  }

  void
  getContactList(ContactList& contactList)
  {
    contactList.clear();
    contactList.insert(contactList.end(), m_contactList.begin(), m_contactList.end());
  }
private:
  ndn::shared_ptr<ndn::IdentityCertificate>
  loadTrustAnchor();

  void
  initializeSecurity();

  void
  fetchCollectEndorse(const ndn::Name& identity);

  void
  fetchEndorseCertificateInternal(const ndn::Name& identity, int certIndex);

  void
  prepareEndorseInfo(const ndn::Name& identity);

  // PROFILE: self-endorse-certificate
  void
  onDnsSelfEndorseCertValidated(const ndn::shared_ptr<const ndn::Data>& selfEndorseCertificate,
                                const ndn::Name& identity);

  void
  onDnsSelfEndorseCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& selfEndorseCertificate,
                                       const std::string& failInfo,
                                       const ndn::Name& identity);

  void
  onDnsSelfEndorseCertTimeoutNotify(const ndn::Interest& interest,
                                    const ndn::Name& identity);

  // ENDORSED: endorse-collection
  void
  onDnsCollectEndorseValidated(const ndn::shared_ptr<const ndn::Data>& data,
                               const ndn::Name& identity);

  void
  onDnsCollectEndorseValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
                                      const std::string& failInfo,
                                      const ndn::Name& identity);

  void
  onDnsCollectEndorseTimeoutNotify(const ndn::Interest& interest,
                                   const ndn::Name& identity);

  // PROFILE-CERT: endorse-certificate
  void
  onEndorseCertificateInternal(const ndn::Interest& interest,
                               ndn::Data& data,
                               const ndn::Name& identity,
                               int certIndex,
                               std::string hash);

  void
  onEndorseCertificateInternalTimeout(const ndn::Interest& interest,
                                      const ndn::Name& identity,
                                      int certIndex);

  // Collect endorsement
  void
  collectEndorsement();

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

  void
  onDnsEndorseeValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
                                const std::string& failInfo);

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

  void
  decreaseCollectStatus();

  void
  publishCollectEndorsedDataInDNS();

  // Identity certificate
  void
  onIdentityCertValidated(const ndn::shared_ptr<const ndn::Data>& data);

  void
  onIdentityCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
                                 const std::string& failInfo);

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

  void
  decreaseIdCertCount();

  // Publish self-endorse certificate
  ndn::shared_ptr<EndorseCertificate>
  getSignedSelfEndorseCertificate(const Profile& profile);

  void
  publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate);

  // Publish endorse certificate
  ndn::shared_ptr<EndorseCertificate>
  generateEndorseCertificate(const ndn::Name& identity);

  void
  publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate);

  // Communication
  void
  sendInterest(const ndn::Interest& interest,
               const ndn::OnDataValidated& onValidated,
               const ndn::OnDataValidationFailed& onValidationFailed,
               const TimeoutNotify& timeoutNotify,
               int retry = 1);

  void
  onTargetData(const ndn::Interest& interest,
               const ndn::Data& data,
               const ndn::OnDataValidated& onValidated,
               const ndn::OnDataValidationFailed& onValidationFailed);

  void
  onTargetTimeout(const ndn::Interest& interest,
                  int retry,
                  const ndn::OnDataValidated& onValidated,
                  const ndn::OnDataValidationFailed& onValidationFailed,
                  const TimeoutNotify& timeoutNotify);

  // DNS listener
  void
  onDnsInterest(const ndn::Name& prefix, const ndn::Interest& interest);

  void
  onDnsRegisterFailed(const ndn::Name& prefix, const std::string& failInfo);

signals:
  void
  contactEndorseInfoReady(const chronos::EndorseInfo& endorseInfo);

  void
  contactInfoFetchFailed(const QString& identity);

  void
  idCertNameListReady(const QStringList& certNameList);

  void
  nameListReady(const QStringList& certNameList);

  void
  idCertReady(const ndn::IdentityCertificate& idCert);

  void
  contactAliasListReady(const QStringList& aliasList);

  void
  contactIdListReady(const QStringList& idList);

  void
  contactInfoReady(const QString& identity,
                   const QString& name,
                   const QString& institute,
                   bool isIntro);

  void
  warning(const QString& msg);

public slots:
  void
  onIdentityUpdated(const QString& identity);

  void
  onFetchContactInfo(const QString& identity);

  void
  onAddFetchedContact(const QString& identity);

  void
  onUpdateProfile();

  void
  onRefreshBrowseContact();

  void
  onFetchIdCert(const QString& certName);

  void
  onAddFetchedContactIdCert(const QString& identity);

  void
  onWaitForContactList();

  void
  onWaitForContactInfo(const QString& identity);

  void
  onRemoveContact(const QString& identity);

  void
  onUpdateAlias(const QString& identity, const QString& alias);

  void
  onUpdateIsIntroducer(const QString& identity, bool isIntro);

  void
  onUpdateEndorseCertificate(const QString& identity);

private:

  class FetchedInfo {
  public:
    ndn::shared_ptr<EndorseCertificate> m_selfEndorseCert;
    ndn::shared_ptr<EndorseCollection> m_endorseCollection;
    std::vector<ndn::shared_ptr<EndorseCertificate> > m_endorseCertList;
    ndn::shared_ptr<EndorseInfo> m_endorseInfo;
  };

  typedef std::map<ndn::Name, FetchedInfo> BufferedContacts;
  typedef std::map<ndn::Name, ndn::shared_ptr<ndn::IdentityCertificate> > BufferedIdCerts;

  typedef boost::recursive_mutex RecLock;
  typedef boost::unique_lock<RecLock> UniqueRecLock;

  // Conf
  ndn::shared_ptr<ContactStorage> m_contactStorage;
  ndn::shared_ptr<ndn::Validator> m_validator;
  ndn::shared_ptr<ndn::Face> m_face;
  ndn::KeyChain m_keyChain;
  ndn::Name m_identity;
  ContactList m_contactList;

  // Buffer
  BufferedContacts m_bufferedContacts;
  BufferedIdCerts m_bufferedIdCerts;

  // Tmp Dns
  const ndn::RegisteredPrefixId* m_dnsListenerId;

  RecLock m_collectCountMutex;
  int m_collectCount;

  RecLock m_idCertCountMutex;
  int m_idCertCount;
};

} // namespace chronos

#endif //CHRONOS_CONTACT_MANAGER_H
