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