// 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 "gtest/gtest.h"

namespace croslog {

class FileChangeWatcherTest : public ::testing::Test,
                              public FileChangeWatcher::Observer {
 public:
  FileChangeWatcherTest() = default;
  ~FileChangeWatcherTest() override = default;

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

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

  uint32_t counter() const { return counter_; }

 private:
  uint32_t counter_ = 0;

  DISALLOW_COPY_AND_ASSIGN(FileChangeWatcherTest);
};

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
