// 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)));
  }
  FileWatcherListener(const FileWatcherListener&) = delete;
  FileWatcherListener& operator=(const FileWatcherListener&) = delete;

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

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));
  }
  MockFileWatcherListener(const MockFileWatcherListener&) = delete;
  MockFileWatcherListener& operator=(const MockFileWatcherListener&) = delete;

  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_;
};

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

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