// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef P2P_SERVER_FAKE_FILE_WATCHER_H__
#define P2P_SERVER_FAKE_FILE_WATCHER_H__

#include "p2p/server/file_watcher.h"

#include <glib.h>

#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file_util.h>

namespace p2p {

namespace server {

// A FileWatcher that doesn't really do anything.
class FakeFileWatcher : public FileWatcher {
 public:
  FakeFileWatcher(const base::FilePath& dir,
                  const std::string& file_extension)
      : dir_(dir), file_extension_(file_extension), source_id_(0) {}

  virtual ~FakeFileWatcher() {
    if (source_id_ != 0)
      g_source_remove(source_id_);
  }

  virtual const std::vector<base::FilePath>& files() const {
    return exposed_files_;
  }

  virtual void SetChangedCallback(
      FileWatcher::FileWatcherCallback changed_callback) {
    changed_callback_ = changed_callback;
  }

  virtual const base::FilePath& dir() const {
    return dir_;
  }

  virtual const std::string& file_extension() const {
    return file_extension_;
  }

  // Fake methods.

  // Add, Remove or Touch a file in the watched directory. Since those
  // functions are intended to be called by a test, the file extension is not
  // checked. This will make the watched directory to emit a call to the
  // provided callback with the appropriate arguments in each case from the main
  // loop.
  bool AddFile(const base::FilePath& filename, size_t file_size) {
    if (files_.find(filename) != files_.end()) return false;
    files_.insert(filename);

    // Schedule the action.
    if (pending_actions_.empty())
      source_id_ = g_idle_add(OnFileChanged, this);
    pending_actions_.push((FileEvent){
        .filename = filename,
        .event_type = kFileAdded,
        .file_size = file_size});
    return true;
  }

  bool RemoveFile(const base::FilePath& filename) {
    if (files_.find(filename) == files_.end()) return false;
    files_.erase(filename);

    // Schedule the action.
    if (pending_actions_.empty())
      source_id_ = g_idle_add(OnFileChanged, this);
    pending_actions_.push((FileEvent){
        .filename = filename,
        .event_type = kFileRemoved,
        .file_size = 0});
    return true;
  }

  bool TouchFile(const base::FilePath& filename, size_t file_size) {
    if (files_.find(filename) != files_.end()) return false;

    // Schedule the action.
    if (pending_actions_.empty())
      source_id_ = g_idle_add(OnFileChanged, this);
    pending_actions_.push((FileEvent){
        .filename = filename,
        .event_type = kFileChanged,
        .file_size = file_size});
    return true;
  }

 private:
  static gboolean OnFileChanged(gpointer user_data) {
    FakeFileWatcher* watcher = reinterpret_cast<FakeFileWatcher*>(user_data);
    const FileEvent& event = watcher->pending_actions_.front();
    char* buf = NULL;

    switch (event.event_type) {
      case kFileAdded:
        watcher->exposed_files_.push_back(event.filename);
        // Create the file on disk to allow the consumer get its file size.
      case kFileChanged:
        // Both kFileAdded and kFileChanged execute this part:
        buf = static_cast<char*>(malloc(event.file_size));
        base::WriteFile(event.filename, buf, event.file_size);
        free(buf);
        break;
      case kFileRemoved:
        watcher->exposed_files_.erase(find(watcher->exposed_files_.begin(),
                                            watcher->exposed_files_.end(),
                                            event.filename));
        unlink(event.filename.value().c_str());
        break;
    }

    // Dispatch the callback. This could add more events to the queue, so we
    // keep the processed event until the callback returns and check empty()
    // later on this function.
    if (!watcher->changed_callback_.is_null())
      watcher->changed_callback_.Run(event.filename, event.event_type);

    watcher->pending_actions_.pop();
    return !watcher->pending_actions_.empty();
  }

  base::FilePath dir_;
  std::string file_extension_;
  FileWatcher::FileWatcherCallback changed_callback_;

  // The list of files in the watched directory once the Add/Remove event was
  // processed. This is what a call to files() will return.
  std::vector<base::FilePath> exposed_files_;

  // The set of files added by the test, used to ensure proper call arguments
  // (i.e. fail when the test attempts to add twice the same file).
  std::set<base::FilePath> files_;

  // The list of pending actions (Add/Remove/Touch) to be processed.
  struct FileEvent {
    base::FilePath filename;
    EventType event_type;
    size_t file_size;
  };
  std::queue<FileEvent> pending_actions_;

  // The source_id used to dispatch file events.
  guint source_id_;

  DISALLOW_COPY_AND_ASSIGN(FakeFileWatcher);
};

}  // namespace server

}  // namespace p2p

#endif  // P2P_SERVER_FAKE_FILE_WATCHER_H__
