// Copyright (c) 2011 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 <stdio.h>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/critical_closure.h"
#include "base/debug/alias.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "starboard/file.h"
#include "starboard/types.h"

namespace base {

namespace {

constexpr auto kDefaultCommitInterval = TimeDelta::FromSeconds(10);

// This enum is used to define the buckets for an enumerated UMA histogram.
// Hence,
//   (a) existing enumerated constants should never be deleted or reordered, and
//   (b) new constants should only be appended at the end of the enumeration.
enum TempFileFailure {
  FAILED_CREATING,
  FAILED_OPENING,
  FAILED_CLOSING,  // Unused.
  FAILED_WRITING,
  FAILED_RENAMING,
  FAILED_FLUSHING,
  TEMP_FILE_FAILURE_MAX
};

// Helper function to write samples to a histogram with a dynamically assigned
// histogram name.  Works with different error code types convertible to int
// which is the actual argument type of UmaHistogramExactLinear.
template <typename SampleType>
void UmaHistogramExactLinearWithSuffix(const char* histogram_name,
                                       StringPiece histogram_suffix,
                                       SampleType add_sample,
                                       SampleType max_sample) {
  static_assert(std::is_convertible<SampleType, int>::value,
                "SampleType should be convertible to int");
  DCHECK(histogram_name);
  std::string histogram_full_name(histogram_name);
  if (!histogram_suffix.empty()) {
    histogram_full_name.append(".");
    histogram_full_name.append(histogram_suffix.data(),
                               histogram_suffix.length());
  }
  UmaHistogramExactLinear(histogram_full_name, static_cast<int>(add_sample),
                          static_cast<int>(max_sample));
}

// Helper function to write samples to a histogram with a dynamically assigned
// histogram name.  Works with short timings from 1 ms up to 10 seconds (50
// buckets) which is the actual argument type of UmaHistogramTimes.
void UmaHistogramTimesWithSuffix(const char* histogram_name,
                                 StringPiece histogram_suffix,
                                 TimeDelta sample) {
  DCHECK(histogram_name);
  std::string histogram_full_name(histogram_name);
  if (!histogram_suffix.empty()) {
    histogram_full_name.append(".");
    histogram_full_name.append(histogram_suffix.data(),
                               histogram_suffix.length());
  }
  UmaHistogramTimes(histogram_full_name, sample);
}

void LogFailure(const FilePath& path,
                StringPiece histogram_suffix,
                TempFileFailure failure_code,
                StringPiece message) {
  UmaHistogramExactLinearWithSuffix("ImportantFile.TempFileFailures",
                                    histogram_suffix, failure_code,
                                    TEMP_FILE_FAILURE_MAX);
  DPLOG(WARNING) << "temp file failure: " << path.value() << " : " << message;
}

// Helper function to call WriteFileAtomically() with a
// std::unique_ptr<std::string>.
void WriteScopedStringToFileAtomically(
    const FilePath& path,
    std::unique_ptr<std::string> data,
    Closure before_write_callback,
    Callback<void(bool success)> after_write_callback,
    const std::string& histogram_suffix) {
  if (!before_write_callback.is_null())
    before_write_callback.Run();

  TimeTicks start_time = TimeTicks::Now();
  bool result =
      ImportantFileWriter::WriteFileAtomically(path, *data, histogram_suffix);
  if (result) {
    UmaHistogramTimesWithSuffix("ImportantFile.TimeToWrite", histogram_suffix,
                                TimeTicks::Now() - start_time);
  }

  if (!after_write_callback.is_null())
    after_write_callback.Run(result);
}

void DeleteTmpFile(const FilePath& tmp_file_path,
                   StringPiece histogram_suffix) {
  if (!DeleteFile(tmp_file_path, false)) {
    UmaHistogramExactLinearWithSuffix(
        "ImportantFile.FileDeleteError", histogram_suffix,
        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
  }
}

}  // namespace

#if defined(STARBOARD)
// static
bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
                                              StringPiece data,
                                              StringPiece histogram_suffix) {
  return SbFileAtomicReplace(path.value().c_str(), data.data(), data.size());
}
#else
// static
bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
                                              StringPiece data,
                                              StringPiece histogram_suffix) {
#if defined(OS_CHROMEOS)
  // On Chrome OS, chrome gets killed when it cannot finish shutdown quickly,
  // and this function seems to be one of the slowest shutdown steps.
  // Include some info to the report for investigation. crbug.com/418627
  // TODO(hashimoto): Remove this.
  struct {
    size_t data_size;
    char path[128];
  } file_info;
  file_info.data_size = data.size();
  strlcpy(file_info.path, path.value().c_str(), arraysize(file_info.path));
  debug::Alias(&file_info);
#endif

  // Write the data to a temp file then rename to avoid data loss if we crash
  // while writing the file. Ensure that the temp file is on the same volume
  // as target file, so it can be moved in one step, and that the temp file
  // is securely created.
  FilePath tmp_file_path;
  if (!CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) {
    UmaHistogramExactLinearWithSuffix(
        "ImportantFile.FileCreateError", histogram_suffix,
        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
    LogFailure(path, histogram_suffix, FAILED_CREATING,
               "could not create temporary file");
    return false;
  }

  File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE);
  if (!tmp_file.IsValid()) {
    UmaHistogramExactLinearWithSuffix(
        "ImportantFile.FileOpenError", histogram_suffix,
        -tmp_file.error_details(), -base::File::FILE_ERROR_MAX);
    LogFailure(path, histogram_suffix, FAILED_OPENING,
               "could not open temporary file");
    DeleteFile(tmp_file_path, false);
    return false;
  }

  // If this fails in the wild, something really bad is going on.
  const int data_length = checked_cast<int32_t>(data.length());
  int bytes_written = tmp_file.Write(0, data.data(), data_length);
  if (bytes_written < data_length) {
    UmaHistogramExactLinearWithSuffix(
        "ImportantFile.FileWriteError", histogram_suffix,
        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
  }
  bool flush_success = tmp_file.Flush();
  tmp_file.Close();

  if (bytes_written < data_length) {
    LogFailure(path, histogram_suffix, FAILED_WRITING,
               "error writing, bytes_written=" + IntToString(bytes_written));
    DeleteTmpFile(tmp_file_path, histogram_suffix);
    return false;
  }

  if (!flush_success) {
    LogFailure(path, histogram_suffix, FAILED_FLUSHING, "error flushing");
    DeleteTmpFile(tmp_file_path, histogram_suffix);
    return false;
  }

  base::File::Error replace_file_error = base::File::FILE_OK;
  if (!ReplaceFile(tmp_file_path, path, &replace_file_error)) {
    UmaHistogramExactLinearWithSuffix("ImportantFile.FileRenameError",
                                      histogram_suffix, -replace_file_error,
                                      -base::File::FILE_ERROR_MAX);
    LogFailure(path, histogram_suffix, FAILED_RENAMING,
               "could not rename temporary file");
    DeleteTmpFile(tmp_file_path, histogram_suffix);
    return false;
  }

  return true;
}
#endif

ImportantFileWriter::ImportantFileWriter(
    const FilePath& path,
    scoped_refptr<SequencedTaskRunner> task_runner,
    const char* histogram_suffix)
    : ImportantFileWriter(path,
                          std::move(task_runner),
                          kDefaultCommitInterval,
                          histogram_suffix) {}

ImportantFileWriter::ImportantFileWriter(
    const FilePath& path,
    scoped_refptr<SequencedTaskRunner> task_runner,
    TimeDelta interval,
    const char* histogram_suffix)
    : path_(path),
      task_runner_(std::move(task_runner)),
      serializer_(nullptr),
      commit_interval_(interval),
      histogram_suffix_(histogram_suffix ? histogram_suffix : ""),
      weak_factory_(this) {
  DCHECK(task_runner_);
}

ImportantFileWriter::~ImportantFileWriter() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // We're usually a member variable of some other object, which also tends
  // to be our serializer. It may not be safe to call back to the parent object
  // being destructed.
  DCHECK(!HasPendingWrite());
}

bool ImportantFileWriter::HasPendingWrite() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return timer().IsRunning();
}

void ImportantFileWriter::WriteNow(std::unique_ptr<std::string> data) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!IsValueInRangeForNumericType<int32_t>(data->length())) {
    NOTREACHED();
    return;
  }

  Closure task = AdaptCallbackForRepeating(
      BindOnce(&WriteScopedStringToFileAtomically, path_, std::move(data),
               std::move(before_next_write_callback_),
               std::move(after_next_write_callback_), histogram_suffix_));

  if (!task_runner_->PostTask(FROM_HERE, MakeCriticalClosure(task))) {
    // Posting the task to background message loop is not expected
    // to fail, but if it does, avoid losing data and just hit the disk
    // on the current thread.
    NOTREACHED();

    task.Run();
  }
  ClearPendingWrite();
}

void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  DCHECK(serializer);
  serializer_ = serializer;

  if (!timer().IsRunning()) {
    timer().Start(
        FROM_HERE, commit_interval_,
        Bind(&ImportantFileWriter::DoScheduledWrite, Unretained(this)));
  }
}

void ImportantFileWriter::DoScheduledWrite() {
  DCHECK(serializer_);
  std::unique_ptr<std::string> data(new std::string);
  if (serializer_->SerializeData(data.get())) {
    WriteNow(std::move(data));
  } else {
    DLOG(WARNING) << "failed to serialize data to be saved in "
                  << path_.value();
  }
  ClearPendingWrite();
}

void ImportantFileWriter::RegisterOnNextWriteCallbacks(
    const Closure& before_next_write_callback,
    const Callback<void(bool success)>& after_next_write_callback) {
  before_next_write_callback_ = before_next_write_callback;
  after_next_write_callback_ = after_next_write_callback;
}

void ImportantFileWriter::ClearPendingWrite() {
  timer().Stop();
  serializer_ = nullptr;
}

void ImportantFileWriter::SetTimerForTesting(OneShotTimer* timer_override) {
  timer_override_ = timer_override;
}

}  // namespace base
