// Copyright 2020 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 "croslog/file_change_watcher.h"

#include <string>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "gtest/gtest.h"

namespace croslog {

class FileChangeWatcherTest : public ::testing::Test,
                              public FileChangeWatcher::Observer {
 public:
  FileChangeWatcherTest() = default;
  FileChangeWatcherTest(const FileChangeWatcherTest&) = delete;
  FileChangeWatcherTest& operator=(const FileChangeWatcherTest&) = delete;

  ~FileChangeWatcherTest() override = default;

  void OnFileContentMaybeChanged() override { counter_++; }
  void OnFileNameMaybeChanged() override {}

  bool WaitForCounterValue(uint32_t target_value) {
    constexpr base::TimeDelta kTinyTimeout = base::Milliseconds(100);
    int max_try = 50;
    while (counter() < target_value) {
      base::PlatformThread::Sleep(kTinyTimeout);
      base::RunLoop().RunUntilIdle();
      if (--max_try == 0)
        return false;
    }
    return true;
  }

  uint32_t counter() const { return counter_; }

 private:
  uint32_t counter_ = 0;
};

TEST_F(FileChangeWatcherTest, FileChange) {
  base::FilePath mount_info;
  std::string test_string = "test";

  FileChangeWatcher* watcher = FileChangeWatcher::GetInstance();

  EXPECT_TRUE(base::CreateTemporaryFile(&mount_info));
  EXPECT_TRUE(watcher->AddWatch(mount_info, this));

  // Open the temporary file and write something twice.
  {
    // Open
    base::File file(mount_info, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(0u, counter());

    // Write
    uint32_t previous_counter = counter();
    EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()),
              test_string.length());
    EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u));

    // Write (append)
    previous_counter = counter();
    EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()),
              test_string.length());
    EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u));

    // Close
    previous_counter = counter();
    file.Close();
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(previous_counter, counter());
  }

  // Open the temporary file again and append something twice.
  {
    // Open
    uint32_t previous_counter = counter();
    base::File file(mount_info, base::File::FLAG_OPEN | base::File::FLAG_WRITE |
                                    base::File::FLAG_APPEND);
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(previous_counter, counter());

    // Write (append)
    previous_counter = counter();
    EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()),
              test_string.length());
    EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u));

    // Close
    previous_counter = counter();
    file.Close();
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(previous_counter, counter());
  }

  watcher->RemoveWatch(mount_info);
}

}  // namespace croslog
