/* -*- 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)
  : m_context(context)
  , m_isNfdRunning(false)
  , m_isConnectedToHub(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(NCC_APPCAST)
#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);
  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_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
