/* -*- 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 "fs-watcher.hpp"
#include "db-helper.hpp"
#include "logging.hpp"

#include <boost/bind.hpp>

#include <QDirIterator>
#include <QRegExp>

using namespace std;
using namespace boost;

_LOG_INIT(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
