/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012-2013 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Jared Lindblom <lindblom@cs.ucla.edu>
 *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
 */

#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(DidDirectoryChanged): " << 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::scheduleDelayOneTimeTask (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 " << dirPath.toStdString());

  // 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.moc"
#include "fs-watcher.cc.moc"
#endif
