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

#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)
  : m_context(context)
  , m_isNfdRunning(false)
  , m_menu(new QMenu(this))
  , m_entryPref(new QAction("Preferences...", 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("https://irl.cs.ucla.edu/~cawka/ndn-control-center.xml")
#endif
  , m_entryQuit(new QAction("Quit", m_menu))
  , m_keyViewerDialog(new ncc::KeyViewerDialog)
  , m_face(face)
{
  connect(m_entryPref, SIGNAL(triggered()), this, SIGNAL(showApp()));
  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);

  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_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) {
    m_tray->setIcon(QIcon(CONNECT_ICON));
    if (isNdnAutoConfigEnabled()) {
      startNdnAutoConfig();
    }
  }
  else {
    m_tray->setIcon(QIcon(DISCONNECT_ICON));
  }
}

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
