/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016, 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 "fs-watcher.hpp"
#include "db-helper.hpp"
#include "logging.hpp"

#include <boost/bind.hpp>

#include <QDirIterator>
#include <QRegExp>

using namespace std;
using namespace boost;

INIT_LOGGER("FsWatcher");

FsWatcher::FsWatcher(QString dirPath, LocalFile_Change_Callback onChange,
                     LocalFile_Change_Callback onDelete, QObject* parent)
  : QObject(parent)
  , m_watcher(new QFileSystemWatcher())
  , m_scheduler(new Scheduler())
  , m_dirPath(dirPath)
  , m_onChange(onChange)
  , m_onDelete(onDelete)
{
  _LOG_DEBUG("Monitor dir: " << m_dirPath.toStdString());
  // add main directory to monitor

  initFileStateDb();

  m_watcher->addPath(m_dirPath);

  // register signals (callback functions)
  connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(DidDirectoryChanged(QString)));
  connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(DidFileChanged(QString)));

  m_scheduler->start();

  Scheduler::scheduleOneTimeTask(m_scheduler, 0,
                                 bind(&FsWatcher::ScanDirectory_NotifyRemovals_Execute, this,
                                      m_dirPath),
                                 "rescan-r-" +
                                   m_dirPath.toStdString()); // only one task will be scheduled per directory

  Scheduler::scheduleOneTimeTask(m_scheduler, 0, bind(&FsWatcher::ScanDirectory_NotifyUpdates_Execute,
                                                      this, m_dirPath),
                                 "rescan-" +
                                   m_dirPath.toStdString()); // only one task will be scheduled per directory
}

FsWatcher::~FsWatcher()
{
  m_scheduler->shutdown();
  sqlite3_close(m_db);
}

void
FsWatcher::DidDirectoryChanged(QString dirPath)
{
  _LOG_DEBUG("Triggered DirPath: " << dirPath.toStdString());

  filesystem::path absPathTriggeredDir(dirPath.toStdString());
  if (!filesystem::exists(filesystem::path(absPathTriggeredDir))) {
    Scheduler::scheduleOneTimeTask(m_scheduler, 0.5,
                                   bind(&FsWatcher::ScanDirectory_NotifyRemovals_Execute, this,
                                        dirPath),
                                   "r-" + dirPath.toStdString()); // only one task will be scheduled per directory
  }
  else {
    // m_executor.execute (bind (&FsWatcher::ScanDirectory_NotifyUpdates_Execute, this, dirPath));
    Scheduler::scheduleOneTimeTask(m_scheduler, 0.5,
                                   bind(&FsWatcher::ScanDirectory_NotifyUpdates_Execute, this,
                                        dirPath),
                                   dirPath.toStdString()); // only one task will be scheduled per directory

    // m_executor.execute (bind (&FsWatcher::ScanDirectory_NotifyUpdates_Execute, this, dirPath));
    Scheduler::scheduleOneTimeTask(m_scheduler, 300,
                                   bind(&FsWatcher::ScanDirectory_NotifyUpdates_Execute, this,
                                        dirPath),
                                   "rescan-" +
                                     dirPath.toStdString()); // only one task will be scheduled per directory

    Scheduler::scheduleOneTimeTask(m_scheduler, 300,
                                   bind(&FsWatcher::ScanDirectory_NotifyRemovals_Execute, this,
                                        m_dirPath),
                                   "rescan-r-" +
                                     m_dirPath.toStdString()); // only one task will be scheduled per directory
  }
}

void
FsWatcher::DidFileChanged(QString filePath)
{
  if (!filePath.startsWith(m_dirPath)) {
    _LOG_ERROR(
      "Got notification about a file not from the monitored directory: " << filePath.toStdString());
    return;
  }
  QString absFilePath = filePath;

  filesystem::path absPathTriggeredFile(filePath.toStdString());
  filePath.remove(0, m_dirPath.size());

  filesystem::path triggeredFile(filePath.toStdString());
  if (filesystem::exists(filesystem::path(absPathTriggeredFile))) {
    _LOG_DEBUG("Triggered UPDATE of file:  " << triggeredFile.relative_path().generic_string());
    // m_onChange (triggeredFile.relative_path ());

    m_watcher->removePath(absFilePath);
    m_watcher->addPath(absFilePath);

    Scheduler::scheduleOneTimeTask(m_scheduler, 0.5, bind(m_onChange, triggeredFile.relative_path()),
                                   triggeredFile.relative_path().string());
  }
  else {
    _LOG_DEBUG("Triggered DELETE of file: " << triggeredFile.relative_path().generic_string());
    // m_onDelete (triggeredFile.relative_path ());

    m_watcher->removePath(absFilePath);

    deleteFile(triggeredFile.relative_path());
    Scheduler::scheduleOneTimeTask(m_scheduler, 0.5, bind(m_onDelete, triggeredFile.relative_path()),
                                   "r-" + triggeredFile.relative_path().string());
  }
}

void
FsWatcher::ScanDirectory_NotifyUpdates_Execute(QString dirPath)
{
  _LOG_TRACE(" >> ScanDirectory_NotifyUpdates_Execute");

  // exclude working only on last component, not the full path; iterating through all directories, even excluded from monitoring
  QRegExp exclude("^(\\.|\\.\\.|\\.chronoshare|.*~|.*\\.swp)$");

  QDirIterator dirIterator(dirPath,
                           QDir::Dirs | QDir::Files | /*QDir::Hidden |*/ QDir::NoSymLinks |
                             QDir::NoDotAndDotDot,
                           QDirIterator::Subdirectories); // directory iterator (recursive)

  // iterate through directory recursively
  while (dirIterator.hasNext()) {
    dirIterator.next();

    // Get FileInfo
    QFileInfo fileInfo = dirIterator.fileInfo();

    QString name = fileInfo.fileName();
    _LOG_DEBUG("+++ Scanning: " << name.toStdString());

    if (!exclude.exactMatch(name)) {
      _LOG_DEBUG("Not excluded file/dir: " << fileInfo.absoluteFilePath().toStdString());
      QString absFilePath = fileInfo.absoluteFilePath();

      // _LOG_DEBUG ("Attempt to add path to watcher: " << absFilePath.toStdString ());
      m_watcher->removePath(absFilePath);
      m_watcher->addPath(absFilePath);

      if (fileInfo.isFile()) {
        QString relFile = absFilePath;
        relFile.remove(0, m_dirPath.size());
        filesystem::path aFile(relFile.toStdString());

        if (
          //!m_fileState->LookupFile (aFile.relative_path ().generic_string ()) /* file does not exist there, but exists locally: added */)
          !fileExists(aFile.relative_path()) /*file does not exist in db, but exists in fs: add */) {
          addFile(aFile.relative_path());
          DidFileChanged(absFilePath);
        }
      }
    }
    else {
      // _LOG_DEBUG ("Excluded file/dir: " << fileInfo.filePath ().toStdString ());
    }
  }
}


void
FsWatcher::ScanDirectory_NotifyRemovals_Execute(QString dirPath)
{
  _LOG_DEBUG("Triggered DirPath: " << dirPath.toStdString());

  filesystem::path absPathTriggeredDir(dirPath.toStdString());
  dirPath.remove(0, m_dirPath.size());

  filesystem::path triggeredDir(dirPath.toStdString());

  /*
  FileItemsPtr files = m_fileState->LookupFilesInFolderRecursively (triggeredDir.relative_path ().generic_string ());
  for (std::list<FileItem>::iterator file = files->begin (); file != files->end (); file ++)
    {
      filesystem::path testFile = filesystem::path (m_dirPath.toStdString ()) / file->filename ();
      _LOG_DEBUG ("Check file for deletion [" << testFile.generic_string () << "]");

      if (!filesystem::exists (testFile))
        {
          if (removeIncomplete || file->is_complete ())
            {
              _LOG_DEBUG ("Notifying about removed file [" << file->filename () << "]");
              m_onDelete (file->filename ());
            }
        }
    }
    */

  vector<string> files;
  getFilesInDir(triggeredDir.relative_path(), files);
  for (vector<string>::iterator file = files.begin(); file != files.end(); file++) {
    filesystem::path targetFile = filesystem::path(m_dirPath.toStdString()) / *file;
    if (!filesystem::exists(targetFile)) {
      deleteFile(*file);
      m_onDelete(*file);
    }
  }
}

const string INIT_DATABASE = "\
CREATE TABLE IF NOT EXISTS                                      \n\
    Files(                                                      \n\
    filename      TEXT NOT NULL,                                \n\
    PRIMARY KEY (filename)                                      \n\
);                                                              \n\
CREATE INDEX filename_index ON Files (filename);                \n\
";

void
FsWatcher::initFileStateDb()
{
  filesystem::path dbFolder =
    filesystem::path(m_dirPath.toStdString()) / ".chronoshare" / "fs_watcher";
  filesystem::create_directories(dbFolder);

  int res = sqlite3_open((dbFolder / "filestate.db").string().c_str(), &m_db);
  if (res != SQLITE_OK) {
    BOOST_THROW_EXCEPTION(Error::Db() << errmsg_info_str("Cannot open database: " +
                                                         (dbFolder / "filestate.db").string()));
  }

  char* errmsg = 0;
  res = sqlite3_exec(m_db, INIT_DATABASE.c_str(), NULL, NULL, &errmsg);
  if (res != SQLITE_OK && errmsg != 0) {
    // _LOG_TRACE ("Init \"error\": " << errmsg);
    cout << "FS-Watcher DB error: " << errmsg << endl;
    sqlite3_free(errmsg);
  }
}

bool
FsWatcher::fileExists(const filesystem::path& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "SELECT * FROM Files WHERE filename = ?;", -1, &stmt, 0);
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
  bool retval = false;
  if (sqlite3_step(stmt) == SQLITE_ROW) {
    retval = true;
  }
  sqlite3_finalize(stmt);

  return retval;
}

void
FsWatcher::addFile(const filesystem::path& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "INSERT OR IGNORE INTO Files (filename) VALUES (?);", -1, &stmt, 0);
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
}

void
FsWatcher::deleteFile(const filesystem::path& filename)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "DELETE FROM Files WHERE filename = ?;", -1, &stmt, 0);
  sqlite3_bind_text(stmt, 1, filename.c_str(), -1, SQLITE_STATIC);
  sqlite3_step(stmt);
  sqlite3_finalize(stmt);
}

void
FsWatcher::getFilesInDir(const filesystem::path& dir, vector<string>& files)
{
  sqlite3_stmt* stmt;
  sqlite3_prepare_v2(m_db, "SELECT * FROM Files WHERE filename LIKE ?;", -1, &stmt, 0);

  string dirStr = dir.string();
  ostringstream escapedDir;
  for (string::const_iterator ch = dirStr.begin(); ch != dirStr.end(); ch++) {
    if (*ch == '%')
      escapedDir << "\\%";
    else
      escapedDir << *ch;
  }
  escapedDir << "/"
             << "%";
  string escapedDirStr = escapedDir.str();
  sqlite3_bind_text(stmt, 1, escapedDirStr.c_str(), escapedDirStr.size(), SQLITE_STATIC);

  while (sqlite3_step(stmt) == SQLITE_ROW) {
    string filename(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
                    sqlite3_column_bytes(stmt, 0));
    files.push_back(filename);
  }

  sqlite3_finalize(stmt);
}

#if WAF
#include "fs-watcher.cc.moc"
#include "fs-watcher.moc"
#endif
