/* -*- 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>
 *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
 */

#include <QApplication>
#include <QMessageBox>
#include <QDir>
#include <QTimer>
#include "controller.hpp"

#ifndef Q_MOC_RUN
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <ndn-cxx/util/random.hpp>
#include "cryptopp.hpp"
#include "logging.h"
#include "conf.hpp"
#include "endorse-info.hpp"
#endif

INIT_LOGGER("chronochat.Controller");

Q_DECLARE_METATYPE(ndn::Name)
Q_DECLARE_METATYPE(ndn::security::Certificate)
Q_DECLARE_METATYPE(chronochat::EndorseInfo)
Q_DECLARE_METATYPE(ndn::Interest)
Q_DECLARE_METATYPE(size_t)
Q_DECLARE_METATYPE(chronochat::ChatroomInfo)
Q_DECLARE_METATYPE(chronochat::Invitation)
Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(ndn::Name::Component)

namespace chronochat {

using std::string;

// constructor & destructor
Controller::Controller(QWidget* parent)
  : QDialog(parent)
  , m_localPrefixDetected(false)
  , m_isInConnectionDetection(false)
  , m_settingDialog(new SettingDialog(this))
  , m_startChatDialog(new StartChatDialog(this))
  , m_profileEditor(new ProfileEditor(this))
  , m_invitationDialog(new InvitationDialog(this))
  , m_invitationRequestDialog(new InvitationRequestDialog(this))
  , m_contactPanel(new ContactPanel(this))
  , m_browseContactDialog(new BrowseContactDialog(this))
  , m_addContactPanel(new AddContactPanel(this))
  , m_discoveryPanel(new DiscoveryPanel(this))
{
  qRegisterMetaType<ndn::Name>("ndn.Name");
  qRegisterMetaType<ndn::security::Certificate>("ndn.security.v2.Certificate");
  qRegisterMetaType<chronochat::EndorseInfo>("EndorseInfo");
  qRegisterMetaType<ndn::Interest>("ndn.Interest");
  qRegisterMetaType<size_t>("size_t");
  qRegisterMetaType<chronochat::ChatroomInfo>("chronochat.Chatroom");
  qRegisterMetaType<chronochat::Invitation>("chronochat.Invitation");
  qRegisterMetaType<std::string>("std.string");
  qRegisterMetaType<ndn::Name::Component>("ndn.Component");


  // Connection to ContactManager
  connect(m_backend.getContactManager(), SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(refreshBrowseContact()),
          m_backend.getContactManager(), SLOT(onRefreshBrowseContact()));
  connect(m_backend.getContactManager(), SIGNAL(contactInfoFetchFailed(const QString&)),
          this, SLOT(onWarning(const QString&)));

  // Connection to SettingDialog
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_settingDialog, SLOT(onIdentityUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(identityUpdated(const QString&)),
          this, SLOT(onIdentityUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(nickUpdated(const QString&)),
          this, SLOT(onNickUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(prefixUpdated(const QString&)),
          this, SLOT(onLocalPrefixConfigured(const QString&)));

  // Connection to ProfileEditor
  connect(this, SIGNAL(closeDBModule()),
          m_profileEditor, SLOT(onCloseDBModule()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_profileEditor, SLOT(onIdentityUpdated(const QString&)));
  connect(m_profileEditor, SIGNAL(updateProfile()),
          m_backend.getContactManager(), SLOT(onUpdateProfile()));

  // Connection to StartChatDialog
  connect(m_startChatDialog, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));

  // Connection to InvitationDialog
  connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)),
          &m_backend, SLOT(onInvitationResponded(const ndn::Name&, bool)));

  // Connection to InvitationRequestDialog
  connect(m_invitationRequestDialog, SIGNAL(invitationRequestResponded(const ndn::Name&, bool)),
          &m_backend, SLOT(onInvitationRequestResponded(const ndn::Name&, bool)));

  // Connection to AddContactPanel
  connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)),
          m_backend.getContactManager(), SLOT(onFetchContactInfo(const QString&)));
  connect(m_addContactPanel, SIGNAL(addContact(const QString&)),
          m_backend.getContactManager(), SLOT(onAddFetchedContact(const QString&)));
  connect(m_backend.getContactManager(),
          SIGNAL(contactEndorseInfoReady(const EndorseInfo&)),
          m_addContactPanel,
          SLOT(onContactEndorseInfoReady(const EndorseInfo&)));

  // Connection to BrowseContactDialog
  connect(m_browseContactDialog, SIGNAL(directAddClicked()),
          this, SLOT(onDirectAdd()));
  connect(m_browseContactDialog, SIGNAL(fetchIdCert(const QString&)),
          m_backend.getContactManager(), SLOT(onFetchIdCert(const QString&)));
  connect(m_browseContactDialog, SIGNAL(addContact(const QString&)),
          m_backend.getContactManager(), SLOT(onAddFetchedContactIdCert(const QString&)));
  connect(m_backend.getContactManager(), SIGNAL(idCertNameListReady(const QStringList&)),
          m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(nameListReady(const QStringList&)),
          m_browseContactDialog, SLOT(onNameListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(idCertReady(const ndn::security::Certificate&)),
          m_browseContactDialog, SLOT(onIdCertReady(const ndn::security::Certificate&)));

  // Connection to ContactPanel
  connect(m_contactPanel, SIGNAL(waitForContactList()),
          m_backend.getContactManager(), SLOT(onWaitForContactList()));
  connect(m_contactPanel, SIGNAL(waitForContactInfo(const QString&)),
          m_backend.getContactManager(), SLOT(onWaitForContactInfo(const QString&)));
  connect(m_contactPanel, SIGNAL(removeContact(const QString&)),
          m_backend.getContactManager(), SLOT(onRemoveContact(const QString&)));
  connect(m_contactPanel, SIGNAL(updateAlias(const QString&, const QString&)),
          m_backend.getContactManager(), SLOT(onUpdateAlias(const QString&, const QString&)));
  connect(m_contactPanel, SIGNAL(updateIsIntroducer(const QString&, bool)),
          m_backend.getContactManager(), SLOT(onUpdateIsIntroducer(const QString&, bool)));
  connect(m_contactPanel, SIGNAL(updateEndorseCertificate(const QString&)),
          m_backend.getContactManager(), SLOT(onUpdateEndorseCertificate(const QString&)));
  connect(m_contactPanel, SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(closeDBModule()),
          m_contactPanel, SLOT(onCloseDBModule()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_contactPanel, SLOT(onIdentityUpdated(const QString&)));
  connect(m_backend.getContactManager(), SIGNAL(contactAliasListReady(const QStringList&)),
          m_contactPanel, SLOT(onContactAliasListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(contactIdListReady(const QStringList&)),
          m_contactPanel, SLOT(onContactIdListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(contactInfoReady(const QString&, const QString&,
                                                                 const QString&, bool)),
          m_contactPanel, SLOT(onContactInfoReady(const QString&, const QString&,
                                                  const QString&, bool)));

  // Connection to backend thread
  connect(&m_backend, SIGNAL(nfdError()),
          this, SLOT(onNfdError()));
  connect(this, SIGNAL(nfdReconnect()),
          &m_backend, SLOT(onNfdReconnect()));
  connect(this, SIGNAL(shutdownBackend()),
          &m_backend, SLOT(shutdown()));
  connect(this, SIGNAL(updateLocalPrefix()),
          &m_backend, SLOT(onUpdateLocalPrefixAction()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          &m_backend, SLOT(onIdentityChanged(const QString&)));
  connect(this, SIGNAL(addChatroom(QString)),
          &m_backend, SLOT(addChatroom(QString)));
  connect(this, SIGNAL(removeChatroom(QString)),
          &m_backend, SLOT(removeChatroom(QString)));

  // Thread notifications:
  // on local prefix udpated:
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          this, SLOT(onLocalPrefixUpdated(const QString&)));
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&)));

  // on invitation validated:
  connect(&m_backend, SIGNAL(invitationValidated(QString, QString, ndn::Name)),
          m_invitationDialog, SLOT(onInvitationReceived(QString, QString, ndn::Name)));
  connect(&m_backend, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));

  // on invitation request received
  connect(&m_backend, SIGNAL(invitationRequestReceived(QString, QString, ndn::Name)),
          m_invitationRequestDialog, SLOT(onInvitationRequestReceived(QString, QString,
                                                                      ndn::Name)));

  // on invitation accepted:
  connect(&m_backend, SIGNAL(startChatroomOnInvitation(chronochat::Invitation, bool)),
          this, SLOT(onStartChatroom2(chronochat::Invitation, bool)));

  m_backend.start();

  initialize();

  m_chatroomDiscoveryBackend
    = new ChatroomDiscoveryBackend(m_localPrefix,
                                   m_identity,
                                   this);

  // connect to chatroom discovery back end
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(localPrefixConfigured(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoRequest(std::string, bool)),
          this, SLOT(onChatroomInfoRequest(std::string, bool)));
  connect(this, SIGNAL(respondChatroomInfoRequest(ChatroomInfo, bool)),
          m_chatroomDiscoveryBackend, SLOT(onRespondChatroomInfoRequest(ChatroomInfo, bool)));
  connect(this, SIGNAL(shutdownDiscoveryBackend()),
          m_chatroomDiscoveryBackend, SLOT(shutdown()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(onIdentityUpdated(const QString&)));
  connect(this, SIGNAL(nfdReconnect()),
          m_chatroomDiscoveryBackend, SLOT(onNfdReconnect()));
  connect(m_chatroomDiscoveryBackend, SIGNAL(nfdError()),
          this, SLOT(onNfdError()));

  // connect chatroom discovery back end with front end
  connect(m_discoveryPanel, SIGNAL(waitForChatroomInfo(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(onWaitForChatroomInfo(const QString&)));
  connect(m_discoveryPanel, SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_discoveryPanel, SLOT(onIdentityUpdated(const QString&)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomListReady(const QStringList&)),
          m_discoveryPanel, SLOT(onChatroomListReady(const QStringList&)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoReady(const ChatroomInfo&, bool)),
          m_discoveryPanel, SLOT(onChatroomInfoReady(const ChatroomInfo&, bool)));
  connect(m_discoveryPanel, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));
  connect(m_discoveryPanel, SIGNAL(sendInvitationRequest(const QString&, const QString&)),
          &m_backend, SLOT(onSendInvitationRequest(const QString&, const QString&)));
  connect(&m_backend, SIGNAL(invitationRequestResult(const std::string&)),
          m_discoveryPanel, SLOT(onInvitationRequestResult(const std::string&)));

  m_chatroomDiscoveryBackend->start();

  createTrayIcon();

  emit updateLocalPrefix();
}

Controller::~Controller()
{
  saveConf();
}

// public methods


// private methods
string
Controller::getDBName()
{
  string dbName("chronos-");

  std::stringstream ss;
  {
    using namespace CryptoPP;

    SHA256 hash;
    StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true,
                 new HashFilter(hash, new HexEncoder(new FileSink(ss), false)));
  }
  dbName.append(ss.str()).append(".db");

  return dbName;
}

void
Controller::openDB()
{
  m_db = QSqlDatabase::addDatabase("QSQLITE");
  QString path = (QDir::home().path());
  path.append(QDir::separator())
    .append(".chronos")
    .append(QDir::separator())
    .append(getDBName().c_str());
  m_db.setDatabaseName(path);

  m_db.open();

  // bool ok = m_db.open();
  // _LOG_DEBUG("DB opened: " << std::boolalpha << ok );
}

void
Controller::initialize()
{
  loadConf();

  openDB();

  emit identityUpdated(QString(m_identity.toUri().c_str()));
}

void
Controller::loadConf()
{
  namespace fs = boost::filesystem;

  fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
  fs::create_directories (chronosDir);

  std::ifstream is((chronosDir / "config").c_str ());
  Conf conf;
  Block confBlock;
  try {
    confBlock = ndn::Block::fromStream(is);
    conf.wireDecode(confBlock);
    m_identity.clear();
    m_identity.append(conf.getIdentity());
    if (conf.getNick().length() != 0)
      m_nick = conf.getNick();
    else
      m_nick = m_identity.get(-1).toUri();
  }
  catch (tlv::Error&) {
    try {
      ndn::KeyChain keyChain;
      m_identity = keyChain.getPib().getDefaultIdentity().getName();
    }
    catch (ndn::security::pib::Pib::Error&) {
      m_identity.clear();
      m_identity.append("chronochat-tmp-identity")
                .append(getRandomString());
    }
    m_nick = m_identity.get(-1).toUri();
  }
}

void
Controller::saveConf()
{
  namespace fs = boost::filesystem;

  fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
  fs::create_directories (chronosDir);

  std::ofstream os((chronosDir / "config").c_str ());
  Conf conf;
  conf.setIdentity(m_identity);
  if (!m_nick.empty())
    conf.setNick(m_nick);
  Block confWire = conf.wireEncode();
  os.write(reinterpret_cast<const char*>(confWire.wire()), confWire.size());

  os.close();
}

void
Controller::createActions()
{
  m_startChatroom = new QAction(tr("Start new chat"), this);
  connect(m_startChatroom, SIGNAL(triggered()), this, SLOT(onStartChatAction()));

  m_settingsAction = new QAction(tr("Settings"), this);
  connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(onSettingsAction()));

  m_editProfileAction = new QAction(tr("Edit profile"), this);
  connect(m_editProfileAction, SIGNAL(triggered()), this, SLOT(onProfileEditorAction()));

  m_contactListAction = new QAction(tr("Contact List"), this);
  connect(m_contactListAction, SIGNAL(triggered()), this, SLOT(onContactListAction()));

  m_addContactAction = new QAction(tr("Add contact"), this);
  connect(m_addContactAction, SIGNAL(triggered()), this, SLOT(onAddContactAction()));

  m_chatroomDiscoveryAction = new QAction(tr("Chatroom Discovery"), this);
  connect(m_chatroomDiscoveryAction, SIGNAL(triggered()), this, SLOT(onChatroomDiscoveryAction()));

  m_updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
  connect(m_updateLocalPrefixAction, SIGNAL(triggered()),
          &m_backend, SLOT(onUpdateLocalPrefixAction()));

  m_minimizeAction = new QAction(tr("Mi&nimize"), this);
  connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(onMinimizeAction()));

  m_quitAction = new QAction(tr("Quit"), this);
  connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuitAction()));

}

void
Controller::createTrayIcon()
{
  createActions();

  m_trayIconMenu = new QMenu(this);
  m_trayIconMenu->addAction(m_startChatroom);
  m_trayIconMenu->addAction(m_chatroomDiscoveryAction);

  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_settingsAction);
  m_trayIconMenu->addAction(m_editProfileAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_contactListAction);
  m_trayIconMenu->addAction(m_addContactAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_updateLocalPrefixAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_minimizeAction);
  m_closeMenu = m_trayIconMenu->addMenu("Close chatroom");
  m_closeMenu->setEnabled(false);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_quitAction);

  m_trayIcon = new QSystemTrayIcon(this);
  m_trayIcon->setContextMenu(m_trayIconMenu);

  m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
  m_trayIcon->setToolTip("ChronoChat System Tray Icon");
  m_trayIcon->setVisible(true);
}

void
Controller::updateMenu()
{
  m_trayIconMenu->clear();
  QMenu* menu = m_trayIconMenu;

  menu->addAction(m_startChatroom);
  menu->addAction(m_chatroomDiscoveryAction);

  menu->addSeparator();
  menu->addAction(m_settingsAction);
  menu->addAction(m_editProfileAction);
  menu->addSeparator();
  menu->addAction(m_contactListAction);
  menu->addAction(m_addContactAction);
  menu->addSeparator();
  {
    ChatActionList::const_iterator it = m_chatActionList.begin();
    ChatActionList::const_iterator end = m_chatActionList.end();
    if (it != end) {
      for (; it != end; it++)
        menu->addAction(it->second);
      menu->addSeparator();
    }
  }
  menu->addAction(m_updateLocalPrefixAction);
  menu->addSeparator();
  menu->addAction(m_minimizeAction);
  m_closeMenu = menu->addMenu("Close chatroom");
  {
    ChatActionList::const_iterator it = m_closeActionList.begin();
    ChatActionList::const_iterator end = m_closeActionList.end();
    if (it == end)
      m_closeMenu->setEnabled(false);
    else
      for (; it != end; it++)
        m_closeMenu->addAction(it->second);
  }
  menu->addSeparator();
  menu->addAction(m_quitAction);
}

string
Controller::getRandomString()
{
  uint32_t r = ndn::random::generateWord32();
  std::stringstream ss;
  {
    using namespace CryptoPP;
    StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
                 new HexEncoder(new FileSink(ss), false));

  }
  // for (int i = 0; i < 8; i++)
  //   {
  //     uint32_t t = r & mask;
  //     if (t < 10)
  //       ss << static_cast<char>(t + 0x30);
  //     else
  //       ss << static_cast<char>(t + 0x57);
  //     r = r >> 4;
  //   }

  return ss.str();
}

void
Controller::addChatDialog(const QString& chatroomName, ChatDialog* chatDialog)
{
  m_chatDialogList[chatroomName.toStdString()] = chatDialog;
  connect(chatDialog, SIGNAL(closeChatDialog(const QString&)),
          this, SLOT(onRemoveChatDialog(const QString&)));
  connect(chatDialog, SIGNAL(showChatMessage(const QString&, const QString&, const QString&)),
          this, SLOT(onShowChatMessage(const QString&, const QString&, const QString&)));
  connect(chatDialog, SIGNAL(resetIcon()),
          this, SLOT(onResetIcon()));
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(localPrefixConfigured(const QString&)),
          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(nfdReconnect()),
          chatDialog->getBackend(), SLOT(onNfdReconnect()));

  // connect chat dialog with discovery backend
  connect(chatDialog->getBackend(), SIGNAL(nfdError()),
          this, SLOT(onNfdError()));
  connect(chatDialog->getBackend(), SIGNAL(newChatroomForDiscovery(ndn::Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onNewChatroomForDiscovery(ndn::Name::Component)));
  connect(chatDialog->getBackend(), SIGNAL(addInRoster(ndn::Name, ndn::Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onAddInRoster(ndn::Name, ndn::Name::Component)));
  connect(chatDialog->getBackend(), SIGNAL(eraseInRoster(ndn::Name, ndn::Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onEraseInRoster(ndn::Name, ndn::Name::Component)));


  QAction* chatAction = new QAction(chatroomName, this);
  m_chatActionList[chatroomName.toStdString()] = chatAction;
  connect(chatAction, SIGNAL(triggered()),
          chatDialog, SLOT(onShow()));

  QAction* closeAction = new QAction(chatroomName, this);
  m_closeActionList[chatroomName.toStdString()] = closeAction;
  connect(closeAction, SIGNAL(triggered()),
          chatDialog, SLOT(shutdown()));

  updateMenu();
}

void
Controller::updateDiscoveryList(const ChatroomInfo& info, bool isAdd)
{
  emit discoverChatroomChanged(info, isAdd);
}

void
Controller::onIdentityUpdated(const QString& identity)
{
  while (!m_chatDialogList.empty()) {
    ChatDialogList::const_iterator it = m_chatDialogList.begin();
    it->second->shutdown();
  }

  emit closeDBModule();

  Name identityName(identity.toStdString());
  m_identity = identityName;

  QTimer::singleShot(500, this, SLOT(onIdentityUpdatedContinued()));
}

void
Controller::onIdentityUpdatedContinued()
{
  QString connection = m_db.connectionName();
  // _LOG_DEBUG("connection name: " << connection.toStdString());
  QSqlDatabase::removeDatabase(connection);
  m_db.close();

  openDB();

  emit identityUpdated(QString(m_identity.toUri().c_str()));
}

void
Controller::onNickUpdated(const QString& nick)
{
  m_nick = nick.toStdString();
}

void
Controller::onLocalPrefixUpdated(const QString& localPrefix)
{
  QString privateLocalPrefix("/private/local");

  if (privateLocalPrefix != localPrefix)
    m_localPrefixDetected = true;
  else
    m_localPrefixDetected = false;

  m_localPrefix = Name(localPrefix.toStdString());
}

void
Controller::onLocalPrefixConfigured(const QString& prefix)
{
  if (!m_localPrefixDetected) {
    m_localPrefix = Name(prefix.toStdString());
    emit localPrefixConfigured(prefix);
  }
}

void
Controller::onStartChatAction()
{
  string chatroom = "chatroom-" + getRandomString();

  m_startChatDialog->setChatroom(chatroom);
  m_startChatDialog->show();
  m_startChatDialog->raise();
}

void
Controller::onSettingsAction()
{
  m_settingDialog->setNick(QString(m_nick.c_str()));
  m_settingDialog->show();
  m_settingDialog->raise();
}

void
Controller::onProfileEditorAction()
{
  m_profileEditor->resetPanel();
  m_profileEditor->show();
  m_profileEditor->raise();
}

void
Controller::onAddContactAction()
{
  emit refreshBrowseContact();
  m_browseContactDialog->show();
  m_browseContactDialog->raise();
}

void
Controller::onContactListAction()
{
  m_contactPanel->show();
  m_contactPanel->raise();
}

void
Controller::onChatroomDiscoveryAction()
{
  m_discoveryPanel->show();
  m_discoveryPanel->raise();
}

void
Controller::onDirectAdd()
{
  m_addContactPanel->show();
  m_addContactPanel->raise();
}

void
Controller::onMinimizeAction()
{
  m_settingDialog->hide();
  m_startChatDialog->hide();
  m_profileEditor->hide();
  m_invitationDialog->hide();
  m_addContactPanel->hide();
  m_discoveryPanel->hide();

  ChatDialogList::iterator it = m_chatDialogList.begin();
  ChatDialogList::iterator end = m_chatDialogList.end();
  for (; it != end; it++)
    it->second->hide();
}

void
Controller::onQuitAction()
{
  while (!m_chatDialogList.empty()) {
    ChatDialogList::const_iterator it = m_chatDialogList.begin();
    it->second->shutdown();
  }

  delete m_settingDialog;
  delete m_startChatDialog;
  delete m_profileEditor;
  delete m_invitationDialog;
  delete m_browseContactDialog;
  delete m_addContactPanel;
  delete m_discoveryPanel;
  if (m_chatroomDiscoveryBackend->isRunning()) {
    emit shutdownDiscoveryBackend();
    m_chatroomDiscoveryBackend->wait();
  }
  delete m_chatroomDiscoveryBackend;

  if (m_backend.isRunning()) {
    emit shutdownBackend();
    m_backend.wait();
  }

  if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) {
    emit shutdownNfdChecker();
    m_nfdConnectionChecker->wait();
  }

  QApplication::quit();
}

void
Controller::onStartChatroom(const QString& chatroomName, bool secured)
{
  Name chatroomPrefix;
  chatroomPrefix.append("ndn")
    .append("broadcast")
    .append("ChronoChat")
    .append("Chatroom")
    .append(chatroomName.toStdString());

  // check if the chatroom exists
  if (m_chatDialogList.find(chatroomName.toStdString()) != m_chatDialogList.end()) {
    QMessageBox::information(this, tr("ChronoChat"),
                             tr("You are creating an existing chatroom."
                                "You can check it in the context memu."));
    return;
  }

  // TODO: We should create a chatroom specific key/cert
  //(which should be created in the first half of this method
  //, but let's use the default one for now.
  Name chatPrefix;
  chatPrefix.append(m_identity).append("CHRONOCHAT-CHATDATA").append(chatroomName.toStdString());

  ChatDialog* chatDialog
    = new ChatDialog(chatroomPrefix,
                     chatPrefix,
                     m_localPrefix,
                     chatroomName.toStdString(),
                     m_nick,
                     true,
                     m_identity,
                     this);

  addChatDialog(chatroomName, chatDialog);
  chatDialog->show();

  emit addChatroom(chatroomName);
}

void
Controller::onStartChatroom2(chronochat::Invitation invitation, bool secured)
{
  QString chatroomName = QString::fromStdString(invitation.getChatroom());
  onStartChatroom(chatroomName, secured);

  ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());

  BOOST_ASSERT(it != m_chatDialogList.end());
  it->second->addSyncAnchor(invitation);
}


void
Controller::onShowChatMessage(const QString& chatroomName, const QString& from, const QString& data)
{
  m_trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(chatroomName),
                          QString("<%1>: %2").arg(from).arg(data),
                          QSystemTrayIcon::Information, 20000);
  m_trayIcon->setIcon(QIcon(":/images/note.png"));
}

void
Controller::onResetIcon()
{
  m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
}

void
Controller::onRemoveChatDialog(const QString& chatroomName)
{
  emit removeChatroom(chatroomName);

  ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());
  if (it != m_chatDialogList.end()) {
    ChatDialog* deletedChat = it->second;
    if (deletedChat)
      delete deletedChat;

    m_chatDialogList.erase(it);

    QAction* chatAction = m_chatActionList[chatroomName.toStdString()];
    QAction* closeAction = m_closeActionList[chatroomName.toStdString()];
    if (chatAction)
      delete chatAction;
    if (closeAction)
      delete closeAction;

    m_chatActionList.erase(chatroomName.toStdString());
    m_closeActionList.erase(chatroomName.toStdString());

    updateMenu();
  }
}

void
Controller::onWarning(const QString& msg)
{
  QMessageBox::information(this, tr("ChronoChat"), msg);
}

void
Controller::onNfdError()
{
  if (m_isInConnectionDetection)
    return;
  // begin a thread

  m_isInConnectionDetection = true;
  m_nfdConnectionChecker = new NfdConnectionChecker(this);

  connect(m_nfdConnectionChecker, SIGNAL(nfdConnected()),
          this, SLOT(onNfdReconnect()));
  connect(this, SIGNAL(shutdownNfdChecker()),
          m_nfdConnectionChecker, SLOT(shutdown()));

  m_nfdConnectionChecker->start();
  QMessageBox::information(this, tr("ChronoChat"), "Nfd is not running");
}

void
Controller::onNfdReconnect()
{
  if (m_nfdConnectionChecker != nullptr && m_nfdConnectionChecker->isRunning()) {
    m_nfdConnectionChecker->wait();
  }
  delete m_nfdConnectionChecker;
  m_nfdConnectionChecker = nullptr;
  m_isInConnectionDetection = false;
  emit nfdReconnect();
}

void
Controller::onChatroomInfoRequest(std::string chatroomName, bool isManager)
{
  auto it = m_chatDialogList.find(chatroomName);
  if (it != m_chatDialogList.end())
    emit respondChatroomInfoRequest(it->second->getChatroomInfo(), isManager);
}

} // namespace chronochat

#if WAF
#include "controller.moc"
// #include "controller.cpp.moc"
#endif
