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

#include <QApplication>
#include <QMessageBox>
#include <QDir>
#include <QTimer>
#include "controller.hpp"
//#include "chatroom-discovery.h"

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

INIT_LOGGER("chronochat.Controller");

Q_DECLARE_METATYPE(ndn::Name)
Q_DECLARE_METATYPE(ndn::IdentityCertificate)
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)

namespace chronochat {

using std::string;

// constructor & destructor
Controller::Controller(QWidget* parent)
  : QDialog(parent)
  , m_localPrefixDetected(false)
  , m_settingDialog(new SettingDialog)
  , m_startChatDialog(new StartChatDialog)
  , m_profileEditor(new ProfileEditor)
  , m_invitationDialog(new InvitationDialog)
  , m_contactPanel(new ContactPanel)
  , m_browseContactDialog(new BrowseContactDialog)
  , m_addContactPanel(new AddContactPanel)
{
  qRegisterMetaType<ndn::Name>("ndn.Name");
  qRegisterMetaType<ndn::IdentityCertificate>("ndn.IdentityCertificate");
  qRegisterMetaType<chronochat::EndorseInfo>("chronochat.EndorseInfo");
  qRegisterMetaType<ndn::Interest>("ndn.Interest");
  qRegisterMetaType<size_t>("size_t");
  qRegisterMetaType<chronochat::ChatroomInfo>("chronos.Chatroom");
  qRegisterMetaType<chronochat::Invitation>("chronos.Invitation");

  // 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 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 chronochat::EndorseInfo&)),
          m_addContactPanel,
          SLOT(onContactEndorseInfoReady(const chronochat::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::IdentityCertificate&)),
          m_browseContactDialog, SLOT(onIdCertReady(const ndn::IdentityCertificate&)));

  // 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(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(invitaionValidated(QString, QString, ndn::Name)),
          m_invitationDialog, SLOT(onInvitationReceived(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();

  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 ());
  ChronoChat::Conf conf;
  if (conf.ParseFromIstream(&is)) {
    m_identity.clear();
    m_identity.append(conf.identity());
    if (conf.has_nick())
      m_nick = conf.nick();
    else
      m_nick = m_identity.get(-1).toUri();
  }
  else {
    m_identity.clear();
    // TODO: change below to system default;
    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 ());
  ChronoChat::Conf conf;
  conf.set_identity(m_identity.toUri());
  if (!m_nick.empty())
    conf.set_nick(m_nick);
  conf.SerializeToOstream(&os);

  os.close();
}

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

  m_discoveryAction = new QAction(tr("Ongoing Chatrooms"), this);
  connect(m_discoveryAction, SIGNAL(triggered()), this, SLOT(onDiscoveryAction()));

  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_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_discoveryAction); // disable discovery temporarily

  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()
{
  QMenu* menu = new QMenu(this);
  QMenu* closeMenu = 0;

  menu->addAction(m_startChatroom);
  // menu->addAction(m_discoveryAction);

  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);
  closeMenu = menu->addMenu("Close chatroom");
  {
    ChatActionList::const_iterator it = m_closeActionList.begin();
    ChatActionList::const_iterator end = m_closeActionList.end();
    if (it == end)
      closeMenu->setEnabled(false);
    else
      for (; it != end; it++)
        closeMenu->addAction(it->second);
  }
  menu->addSeparator();
  menu->addAction(m_quitAction);

  m_trayIcon->setContextMenu(menu);
  delete m_trayIconMenu;
  m_trayIconMenu = menu;
  m_closeMenu = closeMenu;
}

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(chatDialog, SIGNAL(rosterChanged(const chronochat::ChatroomInfo&)),
          this, SLOT(onRosterChanged(const chronochat::ChatroomInfo&)));
  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&)));

  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::onDiscoveryAction()
{
}


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

void
Controller::onProfileEditorAction()
{
  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::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();

  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;

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

  QApplication::quit();
}

void
Controller::onStartChatroom(const QString& chatroomName, bool secured)
{
  Name chatroomPrefix;
  chatroomPrefix.append("ndn")
    .append("broadcast")
    .append("ChronoChat")
    .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-DATA").append(chatroomName.toStdString());

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

  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)
{
  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::onError(const QString& msg)
{
  QMessageBox::critical(this, tr("ChronoChat"), msg, QMessageBox::Ok);
  exit(1);
}

void
Controller::onRosterChanged(const chronochat::ChatroomInfo& info)
{

}

} // namespace chronochat

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