// 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.

#include "p2p/server/file_watcher.h"

#include <arpa/inet.h>
#include <fcntl.h>
#include <glib-object.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cctype>
#include <cinttypes>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include <base/bind.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/threading/simple_thread.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "p2p/common/testutil.h"

using std::vector;

using base::Bind;
using base::FilePath;
using base::Unretained;

using testing::_;
using testing::StrictMock;

using p2p::testutil::kDefaultMainLoopTimeoutMs;
using p2p::testutil::RunGMainLoopUntil;
using p2p::testutil::SetupTestDir;
using p2p::testutil::TeardownTestDir;

namespace p2p {

namespace server {

// ------------------------------------------------------------------------

class FileWatcherListener {
 public:
  explicit FileWatcherListener(FileWatcher* file_watcher) {
    file_watcher->SetChangedCallback(
        Bind(&FileWatcherListener::OnChanged, Unretained(this)));
  }

  virtual void OnChanged(const FilePath& file,
                         FileWatcher::EventType event_type) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(FileWatcherListener);
};

class MockFileWatcherListener : public FileWatcherListener {
 public:
  explicit MockFileWatcherListener(FileWatcher* file_watcher)
      : FileWatcherListener(file_watcher), num_calls_(0) {
    ON_CALL(*this, OnChanged(_, _))
        .WillByDefault(
            testing::InvokeWithoutArgs(this, &MockFileWatcherListener::OnCall));
  }

  MOCK_METHOD(void,
              OnChanged,
              (const FilePath&, FileWatcher::EventType),
              (override));

  // NumCallsReached() returns true when the number of calls to |this|
  // is at least |num_calls|. This is used to terminate the GLib main loop
  // excecution and verify the expectations.
  bool NumCallsReached(int num_calls) const { return num_calls_ >= num_calls; }

 private:
  void OnCall() { num_calls_++; }

  int num_calls_;

  DISALLOW_COPY_AND_ASSIGN(MockFileWatcherListener);
};

// ------------------------------------------------------------------------

// Check that we detect that files are added - this should result in
// two events, one for the file creation event and one for the
// change event that results in touch(1) updating the timestamp.
TEST(FileWatcher, TouchNonExisting) {
  FilePath testdir = SetupTestDir("filewatcher-touch-non-existing");

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("file.p2p"),
                                  FileWatcher::EventType::kFileAdded));
  EXPECT_CALL(listener, OnChanged(testdir.Append("file.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "touch %s", testdir.Append("file.p2p").value().c_str());

  // At this point, all the events should be generated, but the directory
  // watcher could be implemented using polling.
  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 2 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("file.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we detect when a timestamp is updated on an existing
// file that we monitor - this should result in a single event.
TEST(FileWatcher, TouchExisting) {
  FilePath testdir = SetupTestDir("filewatcher-touch-existing");
  EXPECT_COMMAND(0, "touch %s", testdir.Append("existing.p2p").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("existing.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("existing.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "touch %s", testdir.Append("existing.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 1 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("existing.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we detect when a file has been written to.
TEST(FileWatcher, CreateFile) {
  FilePath testdir = SetupTestDir("filewatcher-create-file");

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("new-file.p2p"),
                                  FileWatcher::EventType::kFileAdded));
  EXPECT_CALL(listener, OnChanged(testdir.Append("new-file.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "dd if=/dev/zero of=%s bs=1000 count=1",
                 testdir.Append("new-file.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 2 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("new-file.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we detect when data is appended to a file.
TEST(FileWatcher, AppendToFile) {
  FilePath testdir = SetupTestDir("filewatcher-append-to-file");
  EXPECT_COMMAND(0, "touch %s", testdir.Append("existing.p2p").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("existing.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("existing.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "echo -n xyz >> %s",
                 testdir.Append("existing.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 1 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("existing.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we detect when a file is removed - this should result
// in a single event.
TEST(FileWatcher, RemoveFile) {
  FilePath testdir = SetupTestDir("filewatcher-remove-file");
  EXPECT_COMMAND(0, "touch %s", testdir.Append("file.p2p").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("file.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("file.p2p"),
                                  FileWatcher::EventType::kFileRemoved));
  EXPECT_COMMAND(0, "rm -f %s", testdir.Append("file.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 1 /* num_calls */));

  {
    vector<FilePath> expected_files;
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we detect when a file is renamed into what we match - this
// should result in just a single event
TEST(FileWatcher, RenameInto) {
  FilePath testdir = SetupTestDir("filewatcher-rename-into");

  EXPECT_COMMAND(0, "touch %s", testdir.Append("bar.p2p.tmp").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("bar.p2p"),
                                  FileWatcher::EventType::kFileAdded));
  EXPECT_COMMAND(0, "dd if=/dev/zero of=%s bs=100 count=10",
                 testdir.Append("bar.p2p.tmp").value().c_str());
  int rc = rename(testdir.Append("bar.p2p.tmp").value().c_str(),
                  testdir.Append("bar.p2p").value().c_str());
  EXPECT_EQ(rc, 0);

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 1 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("bar.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that we get a Removed event when a file is renamed away
// from what we match
TEST(FileWatcher, RenameAway) {
  FilePath testdir = SetupTestDir("filewatcher-rename-away");

  EXPECT_COMMAND(0, "touch %s", testdir.Append("foo.p2p").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("foo.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("foo.p2p"),
                                  FileWatcher::EventType::kFileRemoved));
  int rc = rename(testdir.Append("foo.p2p").value().c_str(),
                  testdir.Append("foo.p2p.tmp").value().c_str());
  EXPECT_EQ(rc, 0);
  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 1 /* num_calls */));

  {
    vector<FilePath> expected_files;
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that it monitoring works even when there are existing files.
TEST(FileWatcher, ExistingFiles) {
  FilePath testdir = SetupTestDir("filewatcher-existing-files");
  EXPECT_COMMAND(0, "touch %s", testdir.Append("1.p2p").value().c_str());
  EXPECT_COMMAND(0, "touch %s", testdir.Append("2.p2p").value().c_str());
  EXPECT_COMMAND(0, "touch %s", testdir.Append("3.p2p").value().c_str());

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("1.p2p"));
    expected_files.push_back(testdir.Append("2.p2p"));
    expected_files.push_back(testdir.Append("3.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_CALL(listener, OnChanged(testdir.Append("4.p2p"),
                                  FileWatcher::EventType::kFileAdded));
  EXPECT_CALL(listener, OnChanged(testdir.Append("4.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "touch %s", testdir.Append("4.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 2 /* num_calls */));

  {
    vector<FilePath> expected_files;
    expected_files.push_back(testdir.Append("1.p2p"));
    expected_files.push_back(testdir.Append("2.p2p"));
    expected_files.push_back(testdir.Append("3.p2p"));
    expected_files.push_back(testdir.Append("4.p2p"));
    EXPECT_EQ(watcher->files(), expected_files);
  }

  delete watcher;
  TeardownTestDir(testdir);
}

// Check that activity on non-matching files does not cause any events.
TEST(FileWatcher, ActivityOnNonMatchingFiles) {
  FilePath testdir = SetupTestDir("filewatcher-activity-non-matching");

  FileWatcher* watcher = FileWatcher::Construct(testdir, ".p2p");
  StrictMock<MockFileWatcherListener> listener(watcher);
  EXPECT_COMMAND(0, "touch %s",
                 testdir.Append("non-match.boo").value().c_str());

  // We use a second file to flag the test completion and ensure the event
  // from the non-match.boo file was processed and properly ignored.
  EXPECT_CALL(listener, OnChanged(testdir.Append("match.p2p"),
                                  FileWatcher::EventType::kFileAdded));
  EXPECT_CALL(listener, OnChanged(testdir.Append("match.p2p"),
                                  FileWatcher::EventType::kFileChanged));
  EXPECT_COMMAND(0, "touch %s", testdir.Append("match.p2p").value().c_str());

  RunGMainLoopUntil(kDefaultMainLoopTimeoutMs,
                    Bind(&MockFileWatcherListener::NumCallsReached,
                         Unretained(&listener), 2 /* num_calls */));
  delete watcher;
  TeardownTestDir(testdir);
}

// ------------------------------------------------------------------------

}  // namespace server

}  // namespace p2p
