// 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/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.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() { }
  virtual void SetUp() {
    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_, MessageLoopProxy::current().get());
  EXPECT_FALSE(PathExists(writer.path()));
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  writer.WriteNow("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_, MessageLoopProxy::current().get());
  EXPECT_FALSE(PathExists(writer.path()));
  EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
  successful_write_observer_.ObserveNextSuccessfulWrite(&writer);
  writer.WriteNow("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("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("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_, MessageLoopProxy::current().get());
  writer.set_commit_interval(TimeDelta::FromMilliseconds(25));
  EXPECT_FALSE(writer.HasPendingWrite());
  DataSerializer serializer("foo");
  writer.ScheduleWrite(&serializer);
  EXPECT_TRUE(writer.HasPendingWrite());
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      MessageLoop::QuitWhenIdleClosure(),
      TimeDelta::FromMilliseconds(100));
  MessageLoop::current()->Run();
  EXPECT_FALSE(writer.HasPendingWrite());
  ASSERT_TRUE(PathExists(writer.path()));
  EXPECT_EQ("foo", GetFileContent(writer.path()));
}

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

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

}  // namespace base
