// Copyright (c) 2012 The Chromium 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 "base/files/important_file_writer.h"

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

std::string GetFileContent(const FilePath& path) {
  std::string content;
  if (!ReadFileToString(path, &content)) {
    NOTREACHED();
  }
  return content;
}

class DataSerializer : public ImportantFileWriter::DataSerializer {
 public:
  explicit DataSerializer(const std::string& data) : data_(data) {
  }

  bool SerializeData(std::string* output) override {
    output->assign(data_);
    return true;
  }

 private:
  const std::string data_;
};

class SuccessfulWriteObserver {
 public:
  SuccessfulWriteObserver() : successful_write_observed_(false) {}

  // Register on_successful_write() to be called on the next successful write
  // of |writer|.
  void ObserveNextSuccessfulWrite(ImportantFileWriter* writer);

  // Returns true if a successful write was observed via on_successful_write()
  // and resets the observation state to false regardless.
  bool GetAndResetObservationState();

 private:
  void on_successful_write() {
    EXPECT_FALSE(successful_write_observed_);
    successful_write_observed_ = true;
  }

  bool successful_write_observed_;

  DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteObserver);
};

void SuccessfulWriteObserver::ObserveNextSuccessfulWrite(
    ImportantFileWriter* writer) {
  writer->RegisterOnNextSuccessfulWriteCallback(base::Bind(
      &SuccessfulWriteObserver::on_successful_write, base::Unretained(this)));
}

bool SuccessfulWriteObserver::GetAndResetObservationState() {
  bool was_successful_write_observed = successful_write_observed_;
  successful_write_observed_ = false;
  return was_successful_write_observed;
}

}  // namespace

class ImportantFileWriterTest : public testing::Test {
 public:
  ImportantFileWriterTest() { }
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    file_ = temp_dir_.path().AppendASCII("test-file");
  }

 protected:
  SuccessfulWriteObserver successful_write_observer_;
  FilePath file_;
  MessageLoop loop_;

 private:
  ScopedTempDir temp_dir_;
};

TEST_F(ImportantFileWriterTest, Basic) {
  ImportantFileWriter writer(file_, ThreadTaskRunnerHandle::Get());
  EXPECT_FALSE(PathExists(writer.path()));
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  writer.WriteNow(WrapUnique(new std::string("foo")));
  RunLoop().RunUntilIdle();

  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("foo", GetFileContent(writer.path()));
}

TEST_F(ImportantFileWriterTest, BasicWithSuccessfulWriteObserver) {
  ImportantFileWriter writer(file_, ThreadTaskRunnerHandle::Get());
  EXPECT_FALSE(PathExists(writer.path()));
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  successful_write_observer_.ObserveNextSuccessfulWrite(&writer);
  writer.WriteNow(WrapUnique(new std::string("foo")));
  RunLoop().RunUntilIdle();

  // Confirm that the observer is invoked.
  EXPECT_TRUE(successful_write_observer_.GetAndResetObservationState());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("foo", GetFileContent(writer.path()));

  // Confirm that re-installing the observer works for another write.
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  successful_write_observer_.ObserveNextSuccessfulWrite(&writer);
  writer.WriteNow(WrapUnique(new std::string("bar")));
  RunLoop().RunUntilIdle();

  EXPECT_TRUE(successful_write_observer_.GetAndResetObservationState());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("bar", GetFileContent(writer.path()));

  // Confirm that writing again without re-installing the observer doesn't
  // result in a notification.
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  writer.WriteNow(WrapUnique(new std::string("baz")));
  RunLoop().RunUntilIdle();

  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("baz", GetFileContent(writer.path()));
}

TEST_F(ImportantFileWriterTest, ScheduleWrite) {
  ImportantFileWriter writer(file_,
                             ThreadTaskRunnerHandle::Get(),
                             TimeDelta::FromMilliseconds(25));
  EXPECT_FALSE(writer.HasPendingWrite());
  DataSerializer serializer("foo");
  writer.ScheduleWrite(&serializer);
  EXPECT_TRUE(writer.HasPendingWrite());
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MessageLoop::QuitWhenIdleClosure(),
      TimeDelta::FromMilliseconds(100));
  RunLoop().Run();
  EXPECT_FALSE(writer.HasPendingWrite());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("foo", GetFileContent(writer.path()));
}

TEST_F(ImportantFileWriterTest, DoScheduledWrite) {
  ImportantFileWriter writer(file_, ThreadTaskRunnerHandle::Get());
  EXPECT_FALSE(writer.HasPendingWrite());
  DataSerializer serializer("foo");
  writer.ScheduleWrite(&serializer);
  EXPECT_TRUE(writer.HasPendingWrite());
  writer.DoScheduledWrite();
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MessageLoop::QuitWhenIdleClosure(),
      TimeDelta::FromMilliseconds(100));
  RunLoop().Run();
  EXPECT_FALSE(writer.HasPendingWrite());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("foo", GetFileContent(writer.path()));
}

TEST_F(ImportantFileWriterTest, BatchingWrites) {
  ImportantFileWriter writer(file_,
                             ThreadTaskRunnerHandle::Get(),
                             TimeDelta::FromMilliseconds(25));
  DataSerializer foo("foo"), bar("bar"), baz("baz");
  writer.ScheduleWrite(&foo);
  writer.ScheduleWrite(&bar);
  writer.ScheduleWrite(&baz);
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MessageLoop::QuitWhenIdleClosure(),
      TimeDelta::FromMilliseconds(100));
  RunLoop().Run();
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("baz", GetFileContent(writer.path()));
}

}  // namespace base
