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

#include <google/protobuf/io/zero_copy_stream_impl.h>

#include <fstream>
#include <iostream>
#include <utility>

#include "third_party/statusor/status_macros.h"

namespace cobalt {
namespace util {

using google::protobuf::MessageLite;

const char kTmpSuffix[] = ".tmp";
const char kOverrideSuffix[] = ".override";

ConsistentProtoStore::ConsistentProtoStore(std::string filename,
                                           std::unique_ptr<FileSystem> fs)
    : primary_file_(std::move(filename)),
      tmp_file_(primary_file_ + kTmpSuffix),
      override_file_(primary_file_ + kOverrideSuffix),
      fs_(std::move(fs)) {}

// Write uses a series of operations to write new data. The goal of each of
// these operations is that if the operation is interrupted or fails, the
// store will still be valid.
//
// 1. Ensure a valid state of the files
//    - Check if a file exists at override_file_. A file here indicates an
//      interrupted Write operation, so it is cleaned up by attempting to
//      delete the file at primary_file_, and rename override_file_ to
//      primary_file_. (This is equivalent performing steps 4/5 which were not
//      completed after the previous write)
//
// 2. Write to a temporary file (tmp_file_)
//    - Writing to a file is not atomic, but this temp file is guaranteed
//      never to be read, so if the write is not finished, it is not an issue.
//
// 3. Rename the temp file to override_file_
//    - Renames are as close to an atomic operation you can get in a
//      filesystem. If the rename fails, nothing changes, but if it succeeds,
//      then the store will immediately start reading from this file.
//
// 4. Delete original file (at primary_file_)
//    - Since the Read operation has switched to using the file at
//      override_file_ for read operations, it is safe to delete the
//      original file.
//
// 5. Rename the file at override_file_ to primary_file_
//    - Again, this is a rename so essentially atomic. If this succeeds, then
//      Read operations should immediately switch to using this file. If it
//      fails, the file should still exist at override_file_ so the store
//      should continue reading it successfully.
//
Status ConsistentProtoStore::Write(const MessageLite &proto) {
  // Check if override_file_ exists
  {
    if (fs_->FileExists(override_file_)) {
      DeletePrimary();  // Ignore errors since primary_file_ might not exist
      auto status = MoveOverrideToPrimary();
      if (!status.ok()) {
        // If renaming override_file_ to primary_file_ fails, we should bail
        // since a write operation is not safe.
        return Status(status.error_code(),
                      "Error during recovery: " + status.error_message(),
                      status.error_details());
      }
    }
  }

  RETURN_IF_ERROR(WriteToTmp(proto));
  RETURN_IF_ERROR(MoveTmpToOverride());
  RETURN_IF_ERROR(DeletePrimary());
  RETURN_IF_ERROR(MoveOverrideToPrimary());

  return Status::OK;
}

Status ConsistentProtoStore::Read(MessageLite *proto) {
  {
    std::ifstream new_ifstream(override_file_);
    if (new_ifstream) {
      google::protobuf::io::IstreamInputStream istream(&new_ifstream);
      if (proto->ParseFromZeroCopyStream(&istream)) {
        return Status::OK;
      }
    }
  }

  std::ifstream input(primary_file_);
  if (!input) {
    return Status(StatusCode::NOT_FOUND,
                  "Unable to open the file at `" + primary_file_ + "`",
                  strerror(errno));
  }

  google::protobuf::io::IstreamInputStream istream(&input);
  if (!proto->ParseFromZeroCopyStream(&istream)) {
    return Status(
        StatusCode::INVALID_ARGUMENT,
        "Unable to parse the protobuf from the store. Data is corrupt.");
  }

  if (!input.eof()) {
    return Status(StatusCode::DATA_LOSS,
                  "Reading from the file at `" + primary_file_ +
                      "` did not reach the end of the file.",
                  strerror(errno));
  }

  return Status::OK;
}

Status ConsistentProtoStore::WriteToTmp(const MessageLite &proto) {
  std::ofstream tmpfile(tmp_file_);
  if (!tmpfile) {
    return Status(
        StatusCode::DATA_LOSS,
        "Unable to open the temp file to write the proto `" + tmp_file_ + "`",
        strerror(errno));
  }
  google::protobuf::io::OstreamOutputStream outstream(&tmpfile);
  if (!proto.SerializeToZeroCopyStream(&outstream)) {
    return Status(StatusCode::DATA_LOSS,
                  "Unable to serialize proto to the output stream.");
  }
  if (!tmpfile) {
    return Status(StatusCode::DATA_LOSS,
                  "Writing proto to temp file (" + tmp_file_ + ") failed.",
                  strerror(errno));
  }
  return Status::OK;
}

Status ConsistentProtoStore::MoveTmpToOverride() {
  if (!fs_->Rename(tmp_file_, override_file_)) {
    return Status(
        StatusCode::DATA_LOSS,
        "Unable to rename `" + tmp_file_ + "` => `" + override_file_ + "`.",
        strerror(errno));
  }

  return Status::OK;
}

Status ConsistentProtoStore::DeletePrimary() {
  // If the primary file doesn't exist. We don't care.
  if (!fs_->FileExists(primary_file_)) {
    return Status::OK;
  }

  if (!fs_->Delete(primary_file_)) {
    return Status(StatusCode::ABORTED,
                  "Unable to remove old file `" + primary_file_ + "`.",
                  strerror(errno));
  }

  return Status::OK;
}

Status ConsistentProtoStore::MoveOverrideToPrimary() {
  if (!fs_->Rename(override_file_, primary_file_)) {
    return Status(
        StatusCode::ABORTED,
        "Unable to rename `" + override_file_ + "` => `" + primary_file_ + "`.",
        strerror(errno));
  }

  return Status::OK;
}

}  // namespace util
}  // namespace cobalt
