// Copyright 2018 The Fuchsia 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 <fstream>

#include "util/consistent_proto_store.h"
#include "util/consistent_proto_store_test.pb.h"
#include "util/posix_file_system.h"

#include "./gtest.h"

namespace cobalt {
namespace util {

int path_suffix = 0;
const std::string &test_dir_base = "/tmp/cps_test";

const Status fake_fail(StatusCode::INTERNAL, "BAD", "BAD");

std::string GetTestDirName(const std::string &base) {
  std::stringstream fname;
  fname << base << "_"
        << std::chrono::duration_cast<std::chrono::milliseconds>(
               std::chrono::system_clock::now().time_since_epoch())
               .count()
        << "_" << path_suffix++;
  return fname.str();
}

class TestConsistentProtoStore : public ConsistentProtoStore {
 public:
  explicit TestConsistentProtoStore(std::string filename)
      : ConsistentProtoStore(filename, std::make_unique<PosixFileSystem>()),
        fail_write_tmp_(false),
        fail_move_tmp_(false),
        fail_delete_primary_(false),
        fail_move_override_to_primary_(false) {}

  void FailNextWriteToTmp() { fail_write_tmp_ = true; }
  void FailNextMoveTmpToOverride() { fail_move_tmp_ = true; }
  void FailNextDeletePrimary() { fail_delete_primary_ = true; }
  void FailNextMoveOverrideToPrimary() {
    fail_move_override_to_primary_ = true;
  }

 private:
  Status WriteToTmp(const google::protobuf::MessageLite &proto) override {
    if (fail_write_tmp_) {
      fail_write_tmp_ = false;
      return fake_fail;
    }
    return ConsistentProtoStore::WriteToTmp(proto);
  }

  Status MoveTmpToOverride() override {
    if (fail_move_tmp_) {
      fail_move_tmp_ = false;
      return fake_fail;
    }
    return ConsistentProtoStore::MoveTmpToOverride();
  }

  Status DeletePrimary() override {
    if (fail_delete_primary_) {
      fail_delete_primary_ = false;
      return fake_fail;
    }
    return ConsistentProtoStore::DeletePrimary();
  }

  Status MoveOverrideToPrimary() override {
    if (fail_move_override_to_primary_) {
      fail_move_override_to_primary_ = false;
      return fake_fail;
    }
    return ConsistentProtoStore::MoveOverrideToPrimary();
  }

  bool fail_write_tmp_;
  bool fail_move_tmp_;
  bool fail_delete_primary_;
  bool fail_move_override_to_primary_;
};

class ConsistentProtoStoreTest : public ::testing::Test {
 public:
  ConsistentProtoStoreTest()
      : directory_(GetTestDirName(test_dir_base)),
        store_(directory_ + "/Proto") {}

  void Mkdir() {
    PosixFileSystem fs;
    fs.MakeDirectory(directory_);
  }

  void TearDown() override {
    // Clean up the directory
    PosixFileSystem fs;
    auto files = fs.ListFiles(directory_).ConsumeValueOr({});
    for (auto file : files) {
      fs.Delete(directory_ + "/" + file);
    }
    fs.Delete(directory_);
  }

 protected:
  std::string directory_;
  TestConsistentProtoStore store_;
};

TEST_F(ConsistentProtoStoreTest, DirectoryMissing) {
  TestProto p;
  p.set_b(true);
  auto stat = store_.Write(p);

  EXPECT_FALSE(stat.ok());
  EXPECT_EQ(stat.error_details(), "No such file or directory");

  stat = store_.Read(&p);
  EXPECT_FALSE(stat.ok());
  EXPECT_EQ(stat.error_details(), "No such file or directory");
}

TEST_F(ConsistentProtoStoreTest, NoFileToRead) {
  Mkdir();
  TestProto p;
  auto stat = store_.Read(&p);

  EXPECT_FALSE(stat.ok());
  EXPECT_EQ(stat.error_details(), "No such file or directory");
}

TEST_F(ConsistentProtoStoreTest, Normal) {
  Mkdir();
  TestProto pin, pout;
  pin.set_b(true);
  pin.set_i(42);
  pin.set_s("Data!");
  auto stat = store_.Write(pin);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  stat = store_.Read(&pout);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  EXPECT_EQ(pout.b(), true);
  EXPECT_EQ(pout.i(), 42);
  EXPECT_EQ(pout.s(), "Data!");
}

TEST_F(ConsistentProtoStoreTest, ReadCompatible) {
  Mkdir();
  TestProto pin;
  CompatibleProto pout;
  pin.set_b(true);
  pin.set_i(44);
  auto stat = store_.Write(pin);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  stat = store_.Read(&pout);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  EXPECT_EQ(pout.a_boolean(), true);
}

TEST_F(ConsistentProtoStoreTest, ReadIncompatible) {
  Mkdir();
  TestProto pin;
  IncompatibleProto pout;
  pin.set_s("strang");
  auto stat = store_.Write(pin);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  // Reading an incompatible proto works, but the data is wrong.
  stat = store_.Read(&pout);
  EXPECT_TRUE(stat.ok());
  EXPECT_EQ(stat.error_message(), "");
  EXPECT_EQ(stat.error_details(), "");

  EXPECT_NE(pout.s(), "strang");
}

TEST_F(ConsistentProtoStoreTest, ReadCorrupt) {
  Mkdir();
  {
    std::ofstream f(directory_ + "/Proto");
    f << "Invalid data and stuff";
  }

  TestProto p;
  auto stat = store_.Read(&p);
  EXPECT_FALSE(stat.ok());
  EXPECT_EQ(stat.error_message(),
            "Unable to parse the protobuf from the store. Data is corrupt.");
  EXPECT_EQ(stat.error_details(), "");
}

TEST_F(ConsistentProtoStoreTest, TestFailures) {
  Mkdir();

  TestProto p, pread;
  p.set_b(true);
  p.set_i(10000);
  p.set_s("testing123");

  store_.FailNextWriteToTmp();
  p.set_i(p.i() + 1);
  EXPECT_FALSE(store_.Write(p).ok());
  EXPECT_FALSE(store_.Read(&pread).ok());

  store_.FailNextMoveTmpToOverride();
  p.set_i(p.i() + 1);
  EXPECT_FALSE(store_.Write(p).ok());
  EXPECT_FALSE(store_.Read(&pread).ok());

  store_.FailNextDeletePrimary();
  p.set_i(p.i() + 1);
  EXPECT_FALSE(store_.Write(p).ok());
  // The read should succeed since the tmp file was renamed to new file.
  EXPECT_TRUE(store_.Read(&pread).ok());
  EXPECT_EQ(pread.i(), p.i());

  store_.FailNextDeletePrimary();
  p.set_i(p.i() + 1);
  // This write should succeed, since the delete will fail during recovery,
  // which is ignored.
  EXPECT_TRUE(store_.Write(p).ok());
  EXPECT_TRUE(store_.Read(&pread).ok());
  EXPECT_EQ(pread.i(), p.i());

  store_.FailNextMoveOverrideToPrimary();
  p.set_i(p.i() + 1);
  EXPECT_FALSE(store_.Write(p).ok());
  // A failed finalize should still update the value in the store.
  EXPECT_TRUE(store_.Read(&pread).ok());
  EXPECT_EQ(pread.i(), p.i());

  store_.FailNextMoveTmpToOverride();
  p.set_i(p.i() + 1);
  EXPECT_FALSE(store_.Write(p).ok());
  // If we fail te rename tmp, the value in the store shouldn't change, but it
  // should still be valid.
  EXPECT_TRUE(store_.Read(&pread).ok());
  EXPECT_EQ(pread.i(), p.i() - 1);
}

}  // namespace util
}  // namespace cobalt
