/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014, Regents of the University of California,
 *
 * This file is part of NFD Control Center.  See AUTHORS.md for complete list of NFD
 * authors and contributors.
 *
 * NFD Control Center is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD Control Center 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 NFD
 * Control Center, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * \author Ilya Moiseenko <iliamo@ucla.edu>
 */

#include "config.hpp"

#include "tray-menu.hpp"
#include "ui_traymenu.h"   //generated from traymenu.ui

#include "quit-dialog.hpp"
// #include "fib-input-dialog.hpp"
#include "network-manager.hpp"

#include <QMenu>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QUrl>
#include <QCheckBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QDir>
#include <QScrollBar>
#include <QHBoxLayout>
#include <QVBoxLayout>

TrayMenu::TrayMenu(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::TrayMenu)
{
  processLookup = new QProcess(this);
  QStringList arguments;
  arguments << "-al";
  connect(processLookup,SIGNAL(finished(int)), this, SLOT(parseProcessLookup()));
  processLookup->start("ps",arguments);

  networkManager = new NetworkManager();

  QCoreApplication::setOrganizationName("UCLA");
  QCoreApplication::setOrganizationDomain("named-data.net");
  QCoreApplication::setApplicationName("NDNx Control Center");

  persistentSettings = new QSettings();

  ui->setupUi(this);

  createTrayIcon();
  setIcon(true);
  createToolbar();
  createTableView();

  loadSettings();

  connect(ui->openTrafficMapButton, SIGNAL(pressed()), this, SLOT(openTrafficMap()));
  connect(ui->openRoutingStatusButton, SIGNAL(pressed()), this, SLOT(openRoutingStatus()));
  connect(ui->addFibButton, SIGNAL(pressed()), this, SLOT(showFibInputDialog()));
  // connect(ui->deleteFibButton, SIGNAL(released()), this, SLOT(deleteFibEntry()));
  connect(ui->hubDiscoveryCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeHubDiscovery()));
  connect(ui->loginStartCheckbox, SIGNAL(stateChanged(int)), this, SLOT(changeLoginStart()));
  connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(selectTableRow()));
  connect(ui->openNdnCertificationButton, SIGNAL(released()), this, SLOT(openCertificationPage()));

  statusUpdateThread = new QThread();
  statusUpdateThread->start();

  // daemonStatusTimer = new QTimer(statusUpdateThread);
  // connect(daemonStatusTimer, SIGNAL(timeout()), this, SLOT(daemonStatusUpdate()));
  // daemonStatusTimer->start(2000);

  trayIcon->show();
  model = NULL;
  // dialog = new FibInputDialog(this);

  // urlManager = new QNetworkAccessManager(this);
  // connect(urlManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(runXmlProc(QNetworkReply*)));
}

void TrayMenu::loadSettings()
{
  QVariant value;

  value = persistentSettings->value(ENABLE_HUB_DISCOVERY);
  if(!value.isNull())
    {
      enableHubDiscovery = value.toBool();
      ui->hubDiscoveryCheckbox->setChecked(enableHubDiscovery);
    }
  else
    {
      ui->hubDiscoveryCheckbox->setChecked(true);
      changeHubDiscovery();
    }

  value = persistentSettings->value(ENABLE_START_ON_LOGIN);
  if(!value.isNull())
    {
      enableStartOnLogin = value.toBool();
      ui->loginStartCheckbox->setChecked(enableStartOnLogin);
    }
  else
    {
      ui->loginStartCheckbox->setChecked(false);
      changeLoginStart();
    }
}

void TrayMenu::changeHubDiscovery()
{
  if(ui->hubDiscoveryCheckbox->isChecked())
    {
      enableHubDiscovery = true;
      persistentSettings->setValue(ENABLE_HUB_DISCOVERY, true);
    }
  else
    {
      enableHubDiscovery = false;
      persistentSettings->setValue(ENABLE_HUB_DISCOVERY, false);
    }
}

void TrayMenu::changeLoginStart()
{
  if(ui->loginStartCheckbox->isChecked())
    {
      enableStartOnLogin = true;
      persistentSettings->setValue(ENABLE_START_ON_LOGIN, true);
      makeAutostartDirectory();
    }
  else
    {
      enableStartOnLogin = false;
      persistentSettings->setValue(ENABLE_START_ON_LOGIN, false);

      QProcess *process = new QProcess();
      connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
      QStringList arguments;
      arguments << QDir::homePath() + AUTOSTART_DIRECTORY + SHORTCUT_FILE;
      process->start("rm", arguments);
    }
}

void TrayMenu::makeAutostartDirectory()
{
  QProcess *process = new QProcess();
  connect(process, SIGNAL(finished(int)), this, SLOT(copyFile()));
  connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
  QStringList arguments;
  arguments << QDir::homePath() + AUTOSTART_DIRECTORY;
  process->start("mkdir", arguments);
}

void TrayMenu::copyFile()
{
  QProcess *process = new QProcess();
  connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
  QStringList arguments;
  arguments << QString(RESOURCES_DIR) + "/" + SHORTCUT_FILE << QDir::homePath() + AUTOSTART_DIRECTORY;
  process->start("cp",arguments);
}

void TrayMenu::showFibInputDialog()
{
  // dialog->clear();
  // dialog->exec();
}

void TrayMenu::openTrafficMap()
{
  QDesktopServices::openUrl(QUrl("http://ndnmap.arl.wustl.edu/", QUrl::TolerantMode));
}

void TrayMenu::openRoutingStatus()
{
  QDesktopServices::openUrl(QUrl("http://netlab.cs.memphis.edu/script/htm/status.htm", QUrl::TolerantMode));
}

void TrayMenu::openCertificationPage()
{
  QDesktopServices::openUrl(QUrl("http://ndncert.named-data.net", QUrl::TolerantMode));
}

void TrayMenu::createTrayIcon()
{
  trayIconMenu = new QMenu(this);

  statusIndicator = new QAction("Inactive", this);
  trayIconMenu->addAction(statusIndicator);

  trayIconMenu->addSeparator();

  displayStatus = new QAction("                           Sent / Recv   ", this);
  trayIconMenu->addAction(displayStatus);
  interestSentRecv = new QAction("Interests      0 / 0", this);
  trayIconMenu->addAction(interestSentRecv);
  dataSentRecv = new QAction("Data               0 / 0", this);
  trayIconMenu->addAction(dataSentRecv);

  trayIconMenu->addSeparator();

  open = new QAction("Preferences...", this);
  connect(open, SIGNAL(triggered()), this, SLOT(show()));
  trayIconMenu->addAction(open);

  close = new QAction("Quit", this);
  // connect(close, SIGNAL(triggered()), this, SLOT(confirmQuit()));
  connect(close, SIGNAL(triggered()), qApp, SLOT(quit()));
  trayIconMenu->addAction(close);

  trayIcon = new QSystemTrayIcon(this);
  trayIcon->setContextMenu(trayIconMenu);

  connect(
          trayIcon,
          SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
          this,
          SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason))
          );
}

void TrayMenu::createToolbar()
{
  ui->toolBar->setFloatable(false);
  ui->toolBar->setMovable(false);
  ui->toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
  ui->toolBar->setAllowedAreas(Qt::TopToolBarArea);
  ui->toolBar->setOrientation(Qt::Horizontal);
  ui->toolBar->setIconSize(QSize(32,32));
  ui->toolBar->resize(this->width(), 64);

  openGeneralSettings = new QAction("General", this);
  openGeneralSettings->setIcon(QIcon(":/resource/Resources/preferences-desktop.png"));
  connect(openGeneralSettings,SIGNAL(triggered()),this, SLOT(generalSettingsClicked()));

  openForwardingSettings = new QAction("Forwarding", this);
  openForwardingSettings->setIcon(QIcon(":/resource/Resources/emblem-web.png"));
  connect(openForwardingSettings,SIGNAL(triggered()),this, SLOT(forwardingSettingsClicked()));

  openSecuritySettings = new QAction("Security", this);
  openSecuritySettings->setIcon(QIcon(":/resource/Resources/emblem-system.png"));
  connect(openSecuritySettings,SIGNAL(triggered()),this, SLOT(securitySettingsClicked()));

  ui->toolBar->addAction(openGeneralSettings);
  ui->toolBar->addAction(openForwardingSettings);
  ui->toolBar->addAction(openSecuritySettings);
}

void TrayMenu::generalSettingsClicked()
{
  ui->generalSettingsWidget->show();
  ui->forwardingSettingsWidget->hide();
  ui->securitySettingsWidget->hide();
}

void TrayMenu::forwardingSettingsClicked()
{
  ui->generalSettingsWidget->hide();
  ui->forwardingSettingsWidget->show();
  ui->securitySettingsWidget->hide();
}

void TrayMenu::securitySettingsClicked()
{
  ui->generalSettingsWidget->hide();
  ui->forwardingSettingsWidget->hide();
  ui->securitySettingsWidget->show();
}

void TrayMenu::displayPopup()
{
  trayIcon->showMessage("NDNx Status", statusXml);
}

void TrayMenu::addFibEntry()
{
  // QString name = dialog->getPrefixName();
  // QString tunnelType = dialog->getTunnelType();
  // QString endpoint = dialog->getEndpoint();

  // QStringList arguments;
  // arguments << "add" << name << tunnelType << endpoint;

  // dialog->hide();

  // QProcess *process = new QProcess();
  // connect(process,SIGNAL(finished(int)),process, SLOT(deleteLater()));
  // process->start(NDND_FIB_COMMAND, arguments);
}

void TrayMenu::closeEvent(QCloseEvent *event)
{
  if (trayIcon->isVisible())
    {
      hide();
      event->ignore();
    }
}

void TrayMenu::showEvent(QShowEvent * event)
{
  ui->generalSettingsWidget->show();
  ui->forwardingSettingsWidget->hide();
  ui->securitySettingsWidget->hide();
}

void TrayMenu::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
  if(reason == QSystemTrayIcon::Trigger)
    this->show();
}

void TrayMenu::setIcon(bool isConnected)
{
  if(isConnected)
    trayIcon->setIcon(QIcon(":/resource/Resources/icon-connected-white.png"));
  else
    trayIcon->setIcon(QIcon(":/resource/Resources/icon-disconnected-white.png"));
}

// void TrayMenu::daemonStatusUpdate()
// {
//   urlManager->get(QNetworkRequest(QUrl("http://localhost:6363/?f=xml")));
// }

// void TrayMenu::runXmlProc(QNetworkReply *reply)
// {
//   QByteArray buffer = reply->readAll();
//   applyStatusXslt = new QProcess();

//   QStringList arguments;
//   arguments << QString(RESOURCES_DIR) + "/" + STATUS_XSLT_FILE << "-";
//   connect(applyStatusXslt,SIGNAL(finished(int)), this, SLOT(parseStatusXml()));
//   //connect(applyStatusXslt,SIGNAL(finished(int)), applyStatusXslt, SLOT(deleteLater()));
//   applyStatusXslt->start(XSLTPROC,arguments);
//   applyStatusXslt->write(buffer);
//   applyStatusXslt->closeWriteChannel();

//   applyFibXslt = new QProcess();
//   QStringList args;
//   args << QString(RESOURCES_DIR) + "/" + FIB_XSLT_FILE << "-";
//   connect(applyFibXslt,SIGNAL(finished(int)), this, SLOT(parseFibXml()));
//   //connect(applyFibXslt,SIGNAL(finished(int)), applyFibXslt, SLOT(deleteLater()));
//   applyFibXslt->start(XSLTPROC,args);
//   applyFibXslt->write(buffer);
//   applyFibXslt->closeWriteChannel();
// }

// void TrayMenu::parseStatusXml()
// {
//   QByteArray stdout = applyStatusXslt->readAllStandardOutput();
//   QByteArray stderr = applyStatusXslt->readAllStandardError();
//   applyStatusXslt->deleteLater();

//   statusXml = QString(stdout);

//   if((statusXml == "") || (stderr.length()>0)) // there was an error during Query evaluation
//     {
//       daemonStarted = false;
//       setIcon(false);
//       statusIndicator->setText("Inactive");

//       // QProcess *process = new QProcess();
//       // if(enableHubDiscovery)
//       //     connect(process, SIGNAL(finished(int)), networkManager, SLOT(autoconfigDaemon()));
//       //
//       // connect(process,SIGNAL(finished(int)), process, SLOT(deleteLater()));
//       // process->start(NDND_START_COMMAND);
//     }
//   else
//     {
//       daemonStarted = true;
//       setIcon(true);
//       statusIndicator->setText("Active");

//       QString interestIn = statusXml.mid(statusXml.indexOf("<in>")+4, statusXml.indexOf("</in>") - (statusXml.indexOf("<in>")+4));
//       QString interestOut = statusXml.mid(statusXml.indexOf("<out>")+5, statusXml.indexOf("</out>") - (statusXml.indexOf("<out>")+5));
//       QString dataIn = statusXml.mid(statusXml.lastIndexOf("<in>")+4, statusXml.lastIndexOf("</in>") - (statusXml.lastIndexOf("<in>")+4));
//       QString dataOut = statusXml.mid(statusXml.lastIndexOf("<out>")+5, statusXml.lastIndexOf("</out>") - (statusXml.lastIndexOf("<out>")+5));

//       int i = 0;
//       int k = 0;
//       if((dataOut.length() - interestOut.length()) > 0)
//         {
//           i = dataOut.length() - interestOut.length();
//           i*=2; //because space takes less space than a letter
//         }

//       if((interestOut.length() - dataOut.length()) > 0)
//         {
//           k = interestOut.length() - dataOut.length();
//           k*=2; //because space takes less space than a letter
//         }

//       QString interestStats = QString("%1%2%3%4").arg("Interests",-16,' ').arg(interestOut,6+i,' ').arg(" / ",3).arg(interestIn,-6,' ');
//       QString dataStats = QString("%1%2%3%4").arg("Data",-20,' ').arg(dataOut,6+k,' ').arg(" / ",3).arg(dataIn,-6,' ');

//       //Now I try to align header "Sent / Recv" centrally with the upper line
//       QString padding;
//       for(int j = 0; j < interestStats.indexOf(interestOut); j++)
//         {
//           if(interestStats.at(j)==' ')
//             padding +=" ";
//           else
//             padding += "  "; //because space takes less space than a letter
//         }

//       QString header;
//       int m = 0;
//       if(interestOut.length() - QString("Sent").length() > 0)
//         {
//           m = interestOut.length() - QString("Sent").length();
//           m *=3;
//           header = QString("%1%2").arg(padding).arg("  Sent / Recv",QString("  Sent / Recv").length() + m,' ');
//         }
//       else if(interestOut.length() - QString("Sent").length() < 0)
//         {
//           padding.truncate(padding.length()-(QString("Sent").length() - interestOut.length()));
//           header = padding + "Sent / Recv";
//         }
//       else
//         {
//           header = padding + "  Sent / Recv";
//         }

//       interestSentRecv->setText(interestStats);
//       dataSentRecv->setText(dataStats);
//       displayStatus->setText(header);
//     }
// }

// void TrayMenu::parseFibXml()
// {
//   QByteArray stdout = applyFibXslt->readAllStandardOutput();
//   QByteArray stderr = applyFibXslt->readAllStandardError();
//   applyFibXslt->deleteLater();

//   fibContentsXml = QString(stdout);

//   if((stdout == "") || (stderr.length()>0))
//     return;

//   if ((enableHubDiscovery) && (fibContentsXml.indexOf("ndn:/autoconf-route",0,Qt::CaseInsensitive) == -1))
//     {
//       networkManager->autoconfigDaemon();
//     }

//   QDomDocument xmldoc;
//   QDomElement root;

//   xmldoc.setContent(fibContentsXml);
//   root=xmldoc.documentElement();

//   if(model != NULL)
//     {
//       scrollPosition = ui->tableView->verticalScrollBar()->value();
//       model->clear();
//       delete model;
//     }

//   model = new QStandardItemModel(root.childNodes().count(),3);
//   model->setHorizontalHeaderItem(0, new QStandardItem("NDN prefix"));
//   model->setHorizontalHeaderItem(1, new QStandardItem("Face ID"));
//   model->setHorizontalHeaderItem(2, new QStandardItem("Endpoint"));

//   int row = 0;
//   QDomNode fibEntry=root.firstChild();

//   while (!fibEntry.isNull())
//     {
//       QDomNodeList properties = fibEntry.childNodes();

//       QDomNode faceID = properties.at(0);
//       QDomNode ip =  properties.at(1);
//       QDomNode prefix = properties.at(2);

//       model->setItem(row, 0, new QStandardItem(prefix.toElement().text()));
//       model->setItem(row, 1, new QStandardItem(faceID.toElement().text()));
//       model->setItem(row, 2, new QStandardItem(ip.toElement().text()));

//       fibEntry = fibEntry.nextSibling();
//       row++;
//     }

//   ui->tableView->setModel(model);

//   ui->tableView->setColumnWidth(0, ui->tableView->size().width() / 2 );
//   ui->tableView->setColumnWidth(1, ui->tableView->size().width() / 6 );

//   if(selectedRow >= 0)
//     ui->tableView->selectRow(selectedRow);

//   if(scrollPosition >= 0)
//     ui->tableView->verticalScrollBar()->setValue(scrollPosition);
// }

void TrayMenu::createTableView()
{
  ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
  ui->tableView->horizontalHeader()->setStretchLastSection(true);
  ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
  ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);

  selectedRow = -1;
  scrollPosition = -1;

  QHBoxLayout *hlayout = new QHBoxLayout();
  hlayout->addWidget(ui->addFibButton,0, Qt::AlignLeft);
  // hlayout->addWidget(ui->deleteFibButton, 20, Qt::AlignLeft);

  QVBoxLayout *vlayout = new QVBoxLayout();
  vlayout->addWidget(ui->label);
  vlayout->addWidget(ui->tableView);
  vlayout->addLayout(hlayout);

  ui->forwardingSettingsWidget->setLayout(vlayout);

  QVBoxLayout *expanding = new QVBoxLayout();
  expanding->addWidget(ui->forwardingSettingsWidget);
  ui->centralWidget->setLayout(expanding);
}

void TrayMenu::selectTableRow()
{
  selectedRow = ui->tableView->selectionModel()->selection().indexes().at(0).row();
}

// void TrayMenu::deleteFibEntry()
// {
//   if(selectedRow < 0)
//     return;

//   QStandardItem *prefix = model->item(selectedRow,0);
//   if(prefix == NULL)
//     return;

//   QStandardItem *faceID = model->item(selectedRow,1);
//   if(faceID == NULL)
//     return;

//   QStringList arguments;
//   arguments << "del" << prefix->text() << "face" << faceID->text();

//   QProcess *process = new QProcess();
//   connect(process,SIGNAL(finished(int)), process, SLOT(deleteLater()));
//   process->start(NDND_FIB_COMMAND, arguments);
// }

void TrayMenu::resizeEvent(QResizeEvent *  event)
{
  ui->tableView->setColumnWidth(0, ui->tableView->size().width() / 2);
  ui->tableView->setColumnWidth(1, ui->tableView->size().width() / 6);
}


void TrayMenu::parseProcessLookup()
{
  QByteArray stdout = processLookup->readAllStandardOutput();
  processLookup->deleteLater();

  QString s = QString(stdout);

  if(s == "")
    return;
  else if(s.indexOf("ndnx-control") != s.lastIndexOf("ndnx-control"))
    qApp->quit();
}

TrayMenu::~TrayMenu()
{
  daemonStatusTimer->stop();
  statusUpdateThread->exit(0);
  delete ui;
  delete trayIcon;
  delete trayIconMenu;
  delete open;
  delete close;
  delete openGeneralSettings;
  delete openForwardingSettings;
  delete openSecuritySettings;
  delete statusUpdateThread;
  // delete dialog;
  delete networkManager;
  delete persistentSettings;
}

#if WAF
#include "tray-menu.moc"
#include "tray-menu.cpp.moc"
#endif
