/* -*- 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 ChronoShare, a decentralized file sharing application over NDN.
 *
 * ChronoShare 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.
 *
 * ChronoShare 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 copies of the GNU General Public License along with
 * ChronoShare, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
 */

#include "chronosharegui.hpp"
#include "core/logging.hpp"

#include <QDesktopServices>
#include <QDir>
#include <QFileInfo>
#include <QValidator>

#include <thread>

namespace ndn {
namespace chronoshare {

namespace fs = boost::filesystem;

static const std::string HTTP_SERVER_ADDRESS = "localhost";
static const std::string HTTP_SERVER_PORT = "9001";
#ifdef _DEBUG
static const std::string DOC_ROOT = "gui/html";
#else
static const std::string DOC_ROOT = ":/html";
#endif
static const QString ICON_BIG_FILE(":/images/chronoshare-big.png");
static const QString ICON_TRAY_FILE(":/images/" TRAY_ICON);

_LOG_INIT(Gui);

ChronoShareGui::ChronoShareGui(QWidget* parent)
  : QDialog(parent)
  , m_httpServer(0)
#ifdef SPARKLE_SUPPORTED
  , m_autoUpdate(
      new SparkleAutoUpdate(tr("http://irl.cs.ucla.edu/~zhenkai/chronoshare_dist/chronoshare.xml")))
#endif
{
  setWindowTitle("Settings");
  setMinimumWidth(600);

  labelUsername = new QLabel("Username(hint: /<username>)");
  labelSharedFolder = new QLabel("Shared Folder Name");
  labelSharedFolderPath = new QLabel("Shared Folder Path");

  QRegExp regex("(/[^/]+)+$");
  QValidator* prefixValidator = new QRegExpValidator(regex, this);

  editUsername = new QLineEdit();
  editUsername->setValidator(prefixValidator);

  QRegExp noPureWhiteSpace("^\\S+.*$");
  QValidator* wsValidator = new QRegExpValidator(noPureWhiteSpace, this);
  editSharedFolder = new QLineEdit();
  editSharedFolder->setValidator(wsValidator);

  editSharedFolderPath = new QLineEdit();
  editSharedFolderPath->setReadOnly(true);
  QPalette pal = editSharedFolderPath->palette();
  pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Disabled, QPalette::Base));
  editSharedFolderPath->setPalette(pal);
  button = new QPushButton("Save and apply settings");

  QString versionString = QString("Version: ChronoShare v%1").arg(CHRONOSHARE_VERSION);
  label = new QLabel(versionString, this);

  connect(button, SIGNAL(clicked()), this, SLOT(changeSettings()));

  mainLayout = new QVBoxLayout; // vertically
  mainLayout->addWidget(labelUsername);
  mainLayout->addWidget(editUsername);
  mainLayout->addWidget(labelSharedFolder);
  mainLayout->addWidget(editSharedFolder);
  mainLayout->addWidget(labelSharedFolderPath);
  mainLayout->addWidget(editSharedFolderPath);
  mainLayout->addWidget(button);
  mainLayout->addWidget(label);
  setLayout(mainLayout);

  // create actions that result from clicking a menu option
  createActionsAndMenu();

  // create tray icon
  createTrayIcon();

  // set icon image
  setIcon();

  // show tray icon
  m_trayIcon->show();

  // load settings
  if (!loadSettings()) {
    // prompt user to choose folder
    openMessageBox("First Time Setup",
                   "Please enter a username, shared folder name and choose the shared folder path on your local filesystem.");
    viewSettings();
    openFileDialog();
    viewSettings();
  }
  else {
    if (m_username.isNull() || m_username == "" || m_sharedFolderName.isNull() ||
        m_sharedFolderName == "") {
      openMessageBox("First Time Setup",
                     "To activate ChronoShare, please configure your username and shared folder name.");
      viewSettings();
    }
    else {
      startBackend();
    }
  }
}

void
ChronoShareGui::startBackend(bool restart /*=false*/)
{
  if (m_username.isNull() || m_username == "" || m_sharedFolderName.isNull() ||
      m_sharedFolderName == "" || m_dirPath.isNull() || m_dirPath == "") {
    _LOG_DEBUG("Don't start backend, because settings are in progress or incomplete");
    return;
  }

  if (m_watcher != 0 && m_dispatcher != 0) {
    if (!restart) {
      return;
    }

    _LOG_DEBUG("Restarting Dispatcher and FileWatcher for the new location or new username");
    m_watcher.reset();    // stop filewatching ASAP
    m_dispatcher.reset(); // stop dispatcher ASAP, but after watcher(to prevent triggering callbacks
                          // on deleted object)
  }

  fs::path realPathToFolder(m_dirPath.toStdString());
  realPathToFolder /= m_sharedFolderName.toStdString();

  std::cout << "m_dispatcher username:" << m_username.toStdString()
            << " m_sharedFolderName:" << m_sharedFolderName.toStdString()
            << " realPathToFolder: " << realPathToFolder << std::endl;

  m_ioService.reset(new boost::asio::io_service());
  m_face.reset(new Face(*m_ioService));
  m_dispatcher.reset(new Dispatcher(m_username.toStdString(), m_sharedFolderName.toStdString(),
                                    realPathToFolder, *m_face));

  // Alex: this **must** be here, otherwise m_dirPath will be uninitialized
  m_watcher.reset(new FsWatcher(*m_ioService, realPathToFolder.string().c_str(),
                                bind(&Dispatcher::Did_LocalFile_AddOrModify, m_dispatcher.get(), _1),
                                bind(&Dispatcher::Did_LocalFile_Delete, m_dispatcher.get(), _1)));

  if (m_httpServer != 0) {
    // no need to restart webserver if it already exists
    return;
  }

  QFileInfo indexHtmlInfo(":/html/index.html");
  if (indexHtmlInfo.exists()) {
    try {
      m_httpServer = new http::server::server(HTTP_SERVER_ADDRESS, HTTP_SERVER_PORT, DOC_ROOT);
      m_httpServerThread = std::thread(&http::server::server::run, m_httpServer);
    }
    catch (std::exception& e) {
      _LOG_ERROR("Start http server failed");
      m_httpServer = 0; // just to make sure
      QMessageBox msgBox;
      msgBox.setText("WARNING: Cannot start http server!");
      msgBox.setIcon(QMessageBox::Warning);
      msgBox.setInformativeText(
        QString("Starting http server failed. You will not be able to check history from web "
                "brower. Exception caused: %1")
          .arg(e.what()));
      msgBox.setStandardButtons(QMessageBox::Ok);
      msgBox.exec();
    }
  }
  else {
    _LOG_ERROR("Http server doc root dir does not exist!");
  }
}

ChronoShareGui::~ChronoShareGui()
{
  // stop filewatching ASAP
  m_watcher.reset();

  // stop dispatcher ASAP, but after watcher to prevent triggering callbacks on the deleted object
  m_dispatcher.reset();

  if (m_httpServer != 0) {
    m_httpServer->handle_stop();
    m_httpServerThread.join();
    delete m_httpServer;
  }

  // cleanup
  delete m_trayIcon;
  delete m_trayIconMenu;
#ifdef D_ADHOC_SUPPORTED
  delete m_wifiAction;
#endif
#ifdef SPARKLE_SUPPORTED
  delete m_autoUpdate;
  delete m_checkForUpdates;
#endif
  delete m_openFolder;
  delete m_viewSettings;
  delete m_changeFolder;
  delete m_quitProgram;

  delete labelUsername;
  delete labelSharedFolder;
  delete editUsername;
  delete editSharedFolder;
  delete button;
  delete label;
  delete mainLayout;

  // to avoid `private field 'm_checkForUpdates' is not used` warning/error
  (void)(m_checkForUpdates);
  (void)(m_wifiAction);
}

void
ChronoShareGui::openMessageBox(QString title, QString text)
{
  QMessageBox messageBox(this);
  messageBox.setWindowTitle(title);
  messageBox.setText(text);

  messageBox.setIconPixmap(QPixmap(ICON_BIG_FILE));

  messageBox.exec();
}

void
ChronoShareGui::openMessageBox(QString title, QString text, QString infotext)
{
  QMessageBox messageBox(this);
  messageBox.setWindowTitle(title);
  messageBox.setText(text);
  messageBox.setInformativeText(infotext);

  messageBox.setIconPixmap(QPixmap(ICON_BIG_FILE));

  messageBox.exec();
}

void
ChronoShareGui::createActionsAndMenu()
{
  _LOG_DEBUG("Create actions");

  // create the "open folder" action
  m_openFolder = new QAction(tr("&Open Folder"), this);
  connect(m_openFolder, SIGNAL(triggered()), this, SLOT(openSharedFolder()));

  m_openWeb = new QAction(tr("Open in &Browser"), this);
  connect(m_openWeb, SIGNAL(triggered()), this, SLOT(openInWebBrowser()));

  m_recentFilesMenu = new QMenu(tr("Recently Changed Files"), this);
  for (int i = 0; i < 5; i++) {
    m_fileActions[i] = new QAction(this);
    m_fileActions[i]->setVisible(false);
    connect(m_fileActions[i], SIGNAL(triggered()), this, SLOT(openFile()));
    m_recentFilesMenu->addAction(m_fileActions[i]);
  }
  connect(m_recentFilesMenu, SIGNAL(aboutToShow()), this, SLOT(updateRecentFilesMenu()));

  // create the "view settings" action
  m_viewSettings = new QAction(tr("&View Settings"), this);
  connect(m_viewSettings, SIGNAL(triggered()), this, SLOT(viewSettings()));

  // create the "change folder" action
  m_changeFolder = new QAction(tr("&Change Folder"), this);
  connect(m_changeFolder, SIGNAL(triggered()), this, SLOT(openFileDialog()));

#ifdef SPARKLE_SUPPORTED
  m_checkForUpdates = new QAction(tr("Check For Updates"), this);
  connect(m_checkForUpdates, SIGNAL(triggered()), this, SLOT(onCheckForUpdates()));
#endif

  // create the "quit program" action
  m_quitProgram = new QAction(tr("&Quit"), this);
  connect(m_quitProgram, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void
ChronoShareGui::createTrayIcon()
{
  // create a new icon menu
  m_trayIconMenu = new QMenu(this);

  // add actions to the menu
  m_trayIconMenu->addAction(m_openFolder);
  m_trayIconMenu->addAction(m_openWeb);
  m_trayIconMenu->addMenu(m_recentFilesMenu);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_viewSettings);
  m_trayIconMenu->addAction(m_changeFolder);

#ifdef SPARKLE_SUPPORTED
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_checkForUpdates);
#endif

  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_quitProgram);

  // create new tray icon
  m_trayIcon = new QSystemTrayIcon(this);

  // associate the menu with the tray icon
  m_trayIcon->setContextMenu(m_trayIconMenu);

  // handle left click of icon
  connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this,
          SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
}

void
ChronoShareGui::onCheckForUpdates()
{
#ifdef SPARKLE_SUPPORTED
  cout << "+++++++++++ trying to update +++++++ " << endl;
  m_autoUpdate->checkForUpdates();
  cout << "+++++++++++ end trying to update +++++++ " << endl;
#endif
}

void
ChronoShareGui::setIcon()
{
  // set the icon image
  m_trayIcon->setIcon(QIcon(ICON_TRAY_FILE));
}

void
ChronoShareGui::openSharedFolder()
{
  fs::path realPathToFolder(m_dirPath.toStdString());
  realPathToFolder /= m_sharedFolderName.toStdString();
  QString path = QDir::toNativeSeparators(realPathToFolder.string().c_str());
  QDesktopServices::openUrl(QUrl("file:///" + path));
}

void
ChronoShareGui::openInWebBrowser()
{
  QUrl url("http://localhost:9001/");
  url.setFragment("folderHistory&"
                  "user=" +
                  QUrl::toPercentEncoding(m_username) + "&"
                                                        "folder=" +
                  QUrl::toPercentEncoding(m_sharedFolderName));

  // i give up. there is double encoding and I have no idea how to fight it...
  QDesktopServices::openUrl(url);
}

void
ChronoShareGui::openFile()
{
  // figure out who sent the signal
  QAction* pAction = qobject_cast<QAction*>(sender());
  if (pAction->isEnabled()) {
// we stored full path of the file in this toolTip field
#ifdef Q_WS_MAC
    // we do some hack so we could show the file in Finder highlighted
    QStringList args;
    args << "-e";
    args << "tell application \"Finder\"";
    args << "-e";
    args << "activate";
    args << "-e";
    args << "select POSIX file \"" + pAction->toolTip() + "/" + pAction->text() + "\"";
    args << "-e";
    args << "end tell";
    QProcess::startDetached("osascript", args);
#else
    // too bad qt couldn't do highlighting for Linux(or Mac)
    QDesktopServices::openUrl(QUrl("file:///" + pAction->toolTip()));
#endif
  }
}

void
ChronoShareGui::updateRecentFilesMenu()
{
  for (int i = 0; i < 5; i++) {
    m_fileActions[i]->setVisible(false);
  }
  m_dispatcher->LookupRecentFileActions(std::bind(&ChronoShareGui::checkFileAction, this, _1, _2, _3),
                                        5);
}

void
ChronoShareGui::checkFileAction(const std::string& filename, int action, int index)
{
  fs::path realPathToFolder(m_dirPath.toStdString());
  realPathToFolder /= m_sharedFolderName.toStdString();
  realPathToFolder /= filename;
  QString fullPath = realPathToFolder.string().c_str();
  QFileInfo fileInfo(fullPath);
  if (fileInfo.exists()) {
    // This is a hack, we just use some field to store the path
    m_fileActions[index]->setToolTip(fileInfo.absolutePath());
    m_fileActions[index]->setEnabled(true);
  }
  else {
    // after half an hour frustrating test and search around,
    // I think it's the problem of Qt.
    // According to the Qt doc, the action cannot be clicked
    // and the area would be grey, but it didn't happen
    // User can still trigger the action, and not greyed
    // added check in SLOT to see if the action is "enalbed"
    // as a remedy
    // Give up at least for now
    m_fileActions[index]->setEnabled(false);
    // UPDATE, file not fetched yet
    if (action == 0) {
      QFont font;
      // supposed by change the font, didn't happen
      font.setWeight(QFont::Light);
      m_fileActions[index]->setFont(font);
      m_fileActions[index]->setToolTip(tr("Fetching..."));
    }
    // DELETE
    else {
      QFont font;
      // supposed by change the font, didn't happen
      font.setStrikeOut(true);
      m_fileActions[index]->setFont(font);
      m_fileActions[index]->setToolTip(tr("Deleted..."));
    }
  }
  m_fileActions[index]->setText(fileInfo.fileName());
  m_fileActions[index]->setVisible(true);
}

void
ChronoShareGui::changeSettings()
{
  QString oldUsername = m_username;
  QString oldSharedFolderName = m_sharedFolderName;

  if (!editUsername->text().isEmpty())
    m_username = editUsername->text().trimmed();
  else
    editUsername->setText(m_username);

  if (!editSharedFolder->text().isEmpty())
    m_sharedFolderName = editSharedFolder->text().trimmed();
  else
    editSharedFolder->setText(m_sharedFolderName);

  if (m_username.isNull() || m_username == "" || m_sharedFolderName.isNull() ||
      m_sharedFolderName == "") {
    openMessageBox("Error", "Username and shared folder name cannot be empty");
  }
  else {
    saveSettings();
    this->hide();

    if (m_username != oldUsername || oldSharedFolderName != m_sharedFolderName) {
      startBackend(true); // restart dispatcher/fswatcher
    }
  }
}

void
ChronoShareGui::openFileDialog()
{
  while (true) {
    // prompt user for new directory
    QString tempPath =
      QFileDialog::getExistingDirectory(this, tr("Choose ChronoShare folder"), m_dirPath,
                                        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (tempPath.isNull()) {
      if (m_dirPath.isNull()) {
        openMessageBox("Notice",
                       "ChronoShare will use [" + QDir::homePath() +
                         "/ChronoShare]. \n\nYou can change it later selecting \"Change Folder\" menu.");

        m_dirPath = QDir::homePath() + "/ChronoShare";
        editSharedFolderPath->setText(m_dirPath);
        break;
      }
      else {
        // user just cancelled, no need to do anything else
        return;
      }
    }

    QFileInfo qFileInfo(tempPath);

    if (!qFileInfo.isDir()) {
      openMessageBox("Error", "Please select an existing folder or create a new one.");
      continue;
    }

    if (m_dirPath == tempPath) {
      // user selected the same directory, no need to do anything
      return;
    }

    m_dirPath = tempPath;
    editSharedFolderPath->setText(m_dirPath);
    break;
  }

  _LOG_DEBUG("Selected path: " << m_dirPath.toStdString());
  // save settings
  saveSettings();

  startBackend(true); // restart dispatcher/fswatcher
}

void
ChronoShareGui::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
  // if double clicked, open shared folder
  if (reason == QSystemTrayIcon::DoubleClick) {
    openSharedFolder();
  }
}

void
ChronoShareGui::viewSettings()
{
  //simple for now
  this->show();
  this->raise();
  this->activateWindow();
}

bool
ChronoShareGui::loadSettings()
{
  bool successful = true;

  // Load Settings
  // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
  QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");

  // _LOG_DEBUG(lexical_cast<string>(settings.allKeys()));

  if (settings.contains("username")) {
    m_username = settings.value("username", "admin").toString();
  }
  else {
    successful = false;
  }

  editUsername->setText(m_username);

  if (settings.contains("sharedfoldername")) {
    m_sharedFolderName = settings.value("sharedfoldername", "shared").toString();
  }
  else {
    successful = false;
  }

  editSharedFolder->setText(m_sharedFolderName);

  if (settings.contains("dirPath")) {
    m_dirPath = settings.value("dirPath", QDir::homePath()).toString();
  }
  else {
    successful = false;
  }

  editSharedFolderPath->setText(m_dirPath);

  _LOG_DEBUG("Found configured path: " << (successful ? m_dirPath.toStdString() : std::string("no")));

  return successful;
}

void
ChronoShareGui::saveSettings()
{
  // Save Settings
  // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
  QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");

  settings.setValue("dirPath", m_dirPath);
  settings.setValue("username", m_username);
  settings.setValue("sharedfoldername", m_sharedFolderName);
}

void
ChronoShareGui::closeEvent(QCloseEvent* event)
{
  _LOG_DEBUG("Close Event");

  if (m_username.isNull() || m_username == "" || m_sharedFolderName.isNull() ||
      m_sharedFolderName == "") {
    openMessageBox("ChronoShare is not active",
                   "Username and/or shared folder name are not set.\n\n To activate ChronoShare, "
                   "open Settings menu and configure your username and shared folder name");
  }

  this->hide();
  event->ignore(); // don't let the event propagate to the base class
}

} // namespace chronoshare
} // namespace ndn

#include "chronosharegui.moc"
