/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017, 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/>.
 */

#include "tray-menu.hpp"
#include "tray-menu.moc"

#include <chrono>
#include <functional>

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/interest.hpp>
#include <boost/algorithm/string/replace.hpp>

#ifdef OSX_BUILD
#define CONNECT_ICON ":/res/icon-connected-black.png"
#define DISCONNECT_ICON ":/res/icon-disconnected-black.png"
#define CONNECT_STATUS_ICON ":/res/icon-connected-status-black.png"

#include <Security/Authorization.h>
#include <Security/AuthorizationTags.h>

#include "build/NFD/build/core/version.hpp"
#include "build/ndn-tools/build/core/version.cpp"

#else
#define CONNECT_ICON ":/res/icon-connected-white.png"
#define DISCONNECT_ICON ":/res/icon-disconnected-white.png"

#endif // OSX_BUILD

#include <ndn-cxx/version.hpp>

namespace ndn {
namespace ncc {

/**
 * @brief Maximum number of lines that can show up in auto-config status tab view
 */
const int MAX_LINES_IN_AUTOCONF_STATUS = 100;

#ifdef OSX_BUILD
const QString AUTO_START_SUFFIX = "Library/LaunchAgents/net.named-data.control-center.plist";
#endif // OSX_BUILD

TrayMenu::TrayMenu(QQmlContext* context, Face& face, KeyChain& keyChain)
  : m_context(context)
  , m_isNfdRunning(false)
  , m_isConnectedToHub(false)
  , m_menu(new QMenu(this))
  , m_entryPref(new QAction("Preferences...", m_menu))
  , m_entryStatus(new QAction("Status...", m_menu))
  , m_entrySec(new QAction("Security...", m_menu))
  , m_acProc(nullptr)
  , m_settings(new QSettings())
#ifdef OSX_BUILD
  , m_entryEnableCli(new QAction("Enable Command Terminal Usage...", m_menu))
  , m_checkForUpdates(new QAction("Check for updates", m_menu))
  , m_sparkle(NCC_APPCAST)
#endif
  , m_entryQuit(new QAction("Quit", m_menu))
  , m_keyViewerDialog(new ncc::KeyViewerDialog)
  , m_face(face)
  , m_keyChain(keyChain)
  , m_statusViewer(new StatusViewer(m_face, m_keyChain))
{
  connect(m_entryPref, SIGNAL(triggered()), this, SIGNAL(showApp()));
  connect(m_entryStatus, SIGNAL(triggered()), m_statusViewer, SLOT(present()));
  connect(m_entrySec, SIGNAL(triggered()), m_keyViewerDialog, SLOT(present()));
  connect(m_entryQuit, SIGNAL(triggered()), this, SLOT(quitApp()));

  connect(this, SIGNAL(nfdActivityUpdate(bool)), this, SLOT(updateNfdActivityIcon(bool)),
          Qt::QueuedConnection);
  connect(this, SIGNAL(connectivityUpdate(bool)), this, SLOT(updateConnectivity(bool)),
          Qt::QueuedConnection);

  QString nccVersion = QString(NCC_VERSION) + " (ndn-cxx: " + NDN_CXX_VERSION_BUILD_STRING +
    ", NFD: " + NFD_VERSION_BUILD_STRING +
    ", ndn-tools: " + ::ndn::tools::VERSION +
    ")";

  m_context->setContextProperty("nccVersion", nccVersion);

  m_menu->addAction(m_entryPref);
  m_menu->addAction(m_entryStatus);
  m_menu->addAction(m_entrySec);

#ifdef OSX_BUILD
  connect(m_entryEnableCli, SIGNAL(triggered()), this, SLOT(enableCli()));
  m_menu->addAction(m_entryEnableCli);

  connect(m_checkForUpdates, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
  m_menu->addAction(m_checkForUpdates);
#endif

  m_menu->addAction(m_entryQuit);
  m_tray = new QSystemTrayIcon(this);
  m_tray->setContextMenu(m_menu);
  m_tray->setIcon(QIcon(DISCONNECT_ICON));
  m_tray->show();

  // delaying for the case when NFD is already started (to avoid starting / to avoid starting autoconfig
  if (isNfdAutoStartEnabled()) {
    scheduleDelayedTask(std::chrono::seconds(5), [this] {
        if (!m_isNfdRunning) {
          startNfd();
        }
      });
  }
}

TrayMenu::~TrayMenu()
{
  // delete for all new's
}

////////////////////////////////////////////////////////////////////////////////
// NFD Control Center start on login

Q_INVOKABLE bool
TrayMenu::isNccAutoStartEnabled() const
{
  QFileInfo file(QDir::home().path() + "/" + AUTO_START_SUFFIX);
  return file.exists() && file.isFile();
}

Q_INVOKABLE void
TrayMenu::enableDisableNccAutoStart(bool isEnabled)
{
  if (isEnabled) {
    QFile file(QDir::home().path() + "/" + AUTO_START_SUFFIX);
    file.open(QIODevice::WriteOnly);

    std::string plist = R"PLIST(<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>net.named-data.control-center</string>
        <key>ProgramArguments</key>
        <array>
            <string>%%PATH%%</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <false/>
    </dict>
</plist>
)PLIST"; //"
    boost::replace_all(plist, "%%PATH%%", QCoreApplication::applicationFilePath().toStdString());
    file.write(plist.data(), plist.size());
    file.close();
  }
  else {
    QFile::remove(QDir::home().path() + "/" + AUTO_START_SUFFIX);
  }
}

////////////////////////////////////////////////////////////////////////////////
// NFD start on launch

Q_INVOKABLE bool
TrayMenu::isNfdAutoStartEnabled() const
{
  return m_settings->value("ENABLE_AUTO_START", false).toBool();
}

Q_INVOKABLE void
TrayMenu::enableDisableNfdAutoStart(bool isEnabled)
{
  m_settings->setValue("ENABLE_AUTO_START", isEnabled);
  if (!m_isNfdRunning) {
    startNfd();
  }
}

void
TrayMenu::startNfd()
{
#ifdef OSX_BUILD
  QProcess* proc = new QProcess();
  connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));
  proc->startDetached((QCoreApplication::applicationDirPath() + "/../Platform/nfd"),
                      QStringList()
                        << "--config"
                        << (QCoreApplication::applicationDirPath() + "/../etc/ndn/nfd.conf"));
#endif
}

void
TrayMenu::stopNfd()
{
#ifdef OSX_BUILD
  QProcess* proc = new QProcess();
  connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));
  proc->startDetached("killall", QStringList() << "nfd");
#endif
}

////////////////////////////////////////////////////////////////////////////////
// NDN Autoconfig

Q_INVOKABLE bool
TrayMenu::isNdnAutoConfigEnabled() const
{
  return m_settings->value("ENABLE_NDN_AUTO_CONFIG", false).toBool();
}

Q_INVOKABLE void
TrayMenu::enableDisableNdnAutoConfig(bool isEnabled)
{
  m_settings->setValue("ENABLE_NDN_AUTO_CONFIG", isEnabled);

  if (isEnabled) {
    startNdnAutoConfig();
  }
  else {
    stopNdnAutoConfig();
  }
}

void
TrayMenu::startNdnAutoConfig()
{
  if (m_acProc != nullptr) {
    return;
  }

  stopNdnAutoConfig(false); // Make sure no more than one auto-config process exist

  if (!m_isNfdRunning) {
    return;
  }

  m_acProc = new QProcess();

  scheduleDelayedTask(std::chrono::seconds(2), [this] {
      appendNdnAutoConfigStatus("NDN auto configuration starting...\n");
      m_acProc->start(QCoreApplication::applicationDirPath() + "/../Platform/ndn-autoconfig",
                      QStringList() << "--daemon");
      connect(m_acProc, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
      connect(m_acProc, SIGNAL(readyReadStandardError()), this, SLOT(processOutput()));
    });
}

void
TrayMenu::stopNdnAutoConfig(bool appendStatus)
{
  m_acProc = nullptr;
  QProcess* proc = new QProcess();
  connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));
  proc->startDetached("killall", QStringList() << "ndn-autoconfig");
  if (appendStatus) {
    appendNdnAutoConfigStatus("NDN auto configuration stopped\n");
  }
}

void
TrayMenu::appendNdnAutoConfigStatus(const QString& message)
{
  if (message == "") {
    return;
  }
  if (m_ndnAutoConfigMsg.count("\n") > MAX_LINES_IN_AUTOCONF_STATUS) {
    int end = m_ndnAutoConfigMsg.indexOf("\n");
    m_ndnAutoConfigMsg.remove(0, end + 1);
  }
  m_ndnAutoConfigMsg.append(message);

  m_context->setContextProperty("ndnAutoConfigText", m_ndnAutoConfigMsg);
}

void
TrayMenu::processOutput()
{
  if (m_acProc == nullptr) {
    return;
  }
  appendNdnAutoConfigStatus(m_acProc->readAllStandardOutput());
  appendNdnAutoConfigStatus(m_acProc->readAllStandardError());
}

////////////////////////////////////////////////////////////////////////////////
// NFD stop on shutdown

Q_INVOKABLE bool
TrayMenu::isNfdStopOnExitEnabled() const
{
  return m_settings->value("ENABLE_SHUTDOWN", false).toBool();
}

Q_INVOKABLE void
TrayMenu::enableDisableNfdStopOnExit(bool isEnabled)
{
  m_settings->setValue("ENABLE_SHUTDOWN", isEnabled);
}

////////////////////////////////////////////////////////////////////////////////
// Misc

void
TrayMenu::quitApp()
{
  if (isNfdStopOnExitEnabled()) {
    stopNdnAutoConfig();
    stopNfd();
  }
  QCoreApplication::exit(0);
}

Q_INVOKABLE void
TrayMenu::addDeleteRoute()
{
  addRoute();
}

Q_INVOKABLE void
TrayMenu::addRoute()
{
  std::cout << "Adding route" << std::endl;
  QString cmd = "nfdc register /test tcp4://localhost";
  QProcess *addNewRoute = new QProcess();
  connect(addNewRoute,SIGNAL(finished(int)), addNewRoute, SLOT(deleteLater()));
  addNewRoute->start("bash", QStringList() << "-c" << cmd);
  std::cout << "Done" << std::endl;
}

void
TrayMenu::deleteRoute()
{
  std::cout << "Deleting route" << std::endl;
  QString cmd = "nfdc unregister /test tcp4://localhost";
  QProcess *addNewRoute = new QProcess();
  connect(addNewRoute,SIGNAL(finished(int)), addNewRoute, SLOT(deleteLater()));
  addNewRoute->start("bash", QStringList() << "-c" << cmd);
  std::cout << "Done" << std::endl;
}

void
TrayMenu::updateNfdActivityIcon(bool isActive)
{
  m_isNfdRunning = isActive;

  if (isActive) {
    if(m_isConnectedToHub) {
      m_tray->setIcon(QIcon(CONNECT_STATUS_ICON));
    }
    else {
      m_tray->setIcon(QIcon(CONNECT_ICON));
    }
    if (isNdnAutoConfigEnabled()) {
      startNdnAutoConfig();
    }
  }
  else {
    m_tray->setIcon(QIcon(DISCONNECT_ICON));
  }
}

void
TrayMenu::updateConnectivity(bool isConnectedToHub)
{
  m_isConnectedToHub = isConnectedToHub;
}

void
TrayMenu::enableCli()
{
#ifdef OSX_BUILD
  QProcess* proc = new QProcess();
  connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));

  proc->start("osascript", QStringList()
              << "-e"
              << "do shell script \""
                   "/bin/mkdir -vp /usr/local/bin; "
                   "/bin/ln -s -f '" +  QCoreApplication::applicationDirPath() +
                     "/../Resources/ndn" + "' /usr/local/bin/ndn;"
                   "\" with administrator privileges");
#endif
}

#ifdef OSX_BUILD
void
TrayMenu::checkForUpdates()
{
  m_sparkle.checkForUpdates();
}
#endif // OSX_BUILD

void
TrayMenu::scheduleDelayedTask(std::chrono::milliseconds delays, const std::function<void()>& task)
{
  auto timer = new QTimer();
  timer->setSingleShot(true);
  timer->setInterval(delays);
  connect(timer, &QTimer::timeout,
          [task, timer] {
            task();
            timer->deleteLater();
          });
  timer->start();
}

} // namespace ncc
} // namespace ndn
