// Copyright (c) 2011-2013 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "third_party/leveldatabase/env_chromium_stdio.h"

#if defined(OS_POSIX)
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif

#if defined(OS_WIN)
#include <io.h>
#endif

#include "base/debug/trace_event.h"
#include "base/metrics/histogram.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/leveldatabase/chromium_logger.h"

#if defined(OS_WIN)
#include "base/win/win_util.h"
#endif

using leveldb::ChromiumLogger;
using leveldb::Logger;
using leveldb::RandomAccessFile;
using leveldb::SequentialFile;
using leveldb::Slice;
using leveldb::Status;
using leveldb::WritableFile;

namespace leveldb_env {

namespace {

#if (defined(OS_POSIX) && !defined(OS_LINUX)) || defined(OS_WIN)
// The following are glibc-specific

size_t fread_unlocked(void* ptr, size_t size, size_t n, FILE* file) {
  return fread(ptr, size, n, file);
}

size_t fwrite_unlocked(const void* ptr, size_t size, size_t n, FILE* file) {
  return fwrite(ptr, size, n, file);
}

int fflush_unlocked(FILE* file) { return fflush(file); }

#if !defined(OS_ANDROID)
int fdatasync(int fildes) {
#if defined(OS_WIN)
  return _commit(fildes);
#else
  return HANDLE_EINTR(fsync(fildes));
#endif
}
#endif

#endif

// Wide-char safe fopen wrapper.
FILE* fopen_internal(const char* fname, const char* mode) {
#if defined(OS_WIN)
  return _wfopen(base::UTF8ToUTF16(fname).c_str(),
                 base::ASCIIToUTF16(mode).c_str());
#else
  return fopen(fname, mode);
#endif
}

class ChromiumSequentialFile : public SequentialFile {
 private:
  std::string filename_;
  FILE* file_;
  const UMALogger* uma_logger_;

 public:
  ChromiumSequentialFile(const std::string& fname,
                         FILE* f,
                         const UMALogger* uma_logger)
      : filename_(fname), file_(f), uma_logger_(uma_logger) {}
  virtual ~ChromiumSequentialFile() { fclose(file_); }

  virtual Status Read(size_t n, Slice* result, char* scratch) {
    Status s;
    size_t r = fread_unlocked(scratch, 1, n, file_);
    *result = Slice(scratch, r);
    if (r < n) {
      if (feof(file_)) {
        // We leave status as ok if we hit the end of the file
      } else {
        // A partial read with an error: return a non-ok status
        s = MakeIOError(filename_, strerror(errno), kSequentialFileRead, errno);
        uma_logger_->RecordErrorAt(kSequentialFileRead);
      }
    }
    return s;
  }

  virtual Status Skip(uint64_t n) {
    if (fseek(file_, n, SEEK_CUR)) {
      int saved_errno = errno;
      uma_logger_->RecordErrorAt(kSequentialFileSkip);
      return MakeIOError(
          filename_, strerror(saved_errno), kSequentialFileSkip, saved_errno);
    }
    return Status::OK();
  }
};

class ChromiumRandomAccessFile : public RandomAccessFile {
 private:
  std::string filename_;
  mutable ::base::File file_;
  const UMALogger* uma_logger_;

 public:
  ChromiumRandomAccessFile(const std::string& fname,
                           ::base::File file,
                           const UMALogger* uma_logger)
      : filename_(fname), file_(file.Pass()), uma_logger_(uma_logger) {}
  virtual ~ChromiumRandomAccessFile() {}

  virtual Status Read(uint64_t offset, size_t n, Slice* result, char* scratch)
      const {
    Status s;
    int r = file_.Read(offset, scratch, n);
    *result = Slice(scratch, (r < 0) ? 0 : r);
    if (r < 0) {
      // An error: return a non-ok status
      s = MakeIOError(
          filename_, "Could not perform read", kRandomAccessFileRead);
      uma_logger_->RecordErrorAt(kRandomAccessFileRead);
    }
    return s;
  }
};

}  // unnamed namespace

ChromiumWritableFile::ChromiumWritableFile(const std::string& fname,
                                           FILE* f,
                                           const UMALogger* uma_logger,
                                           WriteTracker* tracker,
                                           bool make_backup)
    : filename_(fname),
      file_(f),
      uma_logger_(uma_logger),
      tracker_(tracker),
      file_type_(kOther),
      make_backup_(make_backup) {
  base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
  if (FilePathToString(path.BaseName()).find("MANIFEST") == 0)
    file_type_ = kManifest;
  else if (ChromiumEnv::HasTableExtension(path))
    file_type_ = kTable;
  if (file_type_ != kManifest)
    tracker_->DidCreateNewFile(filename_);
  parent_dir_ = FilePathToString(ChromiumEnv::CreateFilePath(fname).DirName());
}

ChromiumWritableFile::~ChromiumWritableFile() {
  if (file_ != NULL) {
    // Ignoring any potential errors
    fclose(file_);
  }
}

Status ChromiumWritableFile::SyncParent() {
  Status s;
#if !defined(OS_WIN)
  TRACE_EVENT0("leveldb", "SyncParent");

  int parent_fd = HANDLE_EINTR(open(parent_dir_.c_str(), O_RDONLY));
  if (parent_fd < 0) {
    int saved_errno = errno;
    return MakeIOError(
        parent_dir_, strerror(saved_errno), kSyncParent, saved_errno);
  }
  if (HANDLE_EINTR(fsync(parent_fd)) != 0) {
    int saved_errno = errno;
    s = MakeIOError(
        parent_dir_, strerror(saved_errno), kSyncParent, saved_errno);
  }
  close(parent_fd);
#endif
  return s;
}

Status ChromiumWritableFile::Append(const Slice& data) {
  if (file_type_ == kManifest && tracker_->DoesDirNeedSync(filename_)) {
    Status s = SyncParent();
    if (!s.ok())
      return s;
    tracker_->DidSyncDir(filename_);
  }

  size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);
  if (r != data.size()) {
    int saved_errno = errno;
    uma_logger_->RecordOSError(kWritableFileAppend, saved_errno);
    return MakeIOError(
        filename_, strerror(saved_errno), kWritableFileAppend, saved_errno);
  }
  return Status::OK();
}

Status ChromiumWritableFile::Close() {
  Status result;
  if (fclose(file_) != 0) {
    result = MakeIOError(filename_, strerror(errno), kWritableFileClose, errno);
    uma_logger_->RecordErrorAt(kWritableFileClose);
  }
  file_ = NULL;
  return result;
}

Status ChromiumWritableFile::Flush() {
  Status result;
  if (HANDLE_EINTR(fflush_unlocked(file_))) {
    int saved_errno = errno;
    result = MakeIOError(
        filename_, strerror(saved_errno), kWritableFileFlush, saved_errno);
    uma_logger_->RecordOSError(kWritableFileFlush, saved_errno);
  }
  return result;
}

Status ChromiumWritableFile::Sync() {
  TRACE_EVENT0("leveldb", "ChromiumEnvStdio::Sync");
  Status result;
  int error = 0;

  if (HANDLE_EINTR(fflush_unlocked(file_)))
    error = errno;
  // Sync even if fflush gave an error; perhaps the data actually got out,
  // even though something went wrong.
  if (fdatasync(fileno(file_)) && !error)
    error = errno;
  // Report the first error we found.
  if (error) {
    result = MakeIOError(filename_, strerror(error), kWritableFileSync, error);
    uma_logger_->RecordErrorAt(kWritableFileSync);
  } else if (make_backup_ && file_type_ == kTable) {
    bool success = ChromiumEnv::MakeBackup(filename_);
    uma_logger_->RecordBackupResult(success);
  }
  return result;
}

ChromiumEnvStdio::ChromiumEnvStdio() {}

ChromiumEnvStdio::~ChromiumEnvStdio() {}

Status ChromiumEnvStdio::NewSequentialFile(const std::string& fname,
                                           SequentialFile** result) {
  FILE* f = fopen_internal(fname.c_str(), "rb");
  if (f == NULL) {
    *result = NULL;
    int saved_errno = errno;
    RecordOSError(kNewSequentialFile, saved_errno);
    return MakeIOError(
        fname, strerror(saved_errno), kNewSequentialFile, saved_errno);
  } else {
    *result = new ChromiumSequentialFile(fname, f, this);
    return Status::OK();
  }
}

void ChromiumEnvStdio::RecordOpenFilesLimit(const std::string& type) {
#if defined(OS_POSIX)
  struct rlimit nofile;
  if (getrlimit(RLIMIT_NOFILE, &nofile))
    return;
  GetMaxFDHistogram(type)->Add(nofile.rlim_cur);
#endif
}

Status ChromiumEnvStdio::NewRandomAccessFile(const std::string& fname,
                                             RandomAccessFile** result) {
  int flags = ::base::File::FLAG_READ | ::base::File::FLAG_OPEN;
  ::base::File file(ChromiumEnv::CreateFilePath(fname), flags);
  if (file.IsValid()) {
    *result = new ChromiumRandomAccessFile(fname, file.Pass(), this);
    RecordOpenFilesLimit("Success");
    return Status::OK();
  }
  ::base::File::Error error_code = file.error_details();
  if (error_code == ::base::File::FILE_ERROR_TOO_MANY_OPENED)
    RecordOpenFilesLimit("TooManyOpened");
  else
    RecordOpenFilesLimit("OtherError");
  *result = NULL;
  RecordOSError(kNewRandomAccessFile, error_code);
  return MakeIOError(fname,
                     FileErrorString(error_code),
                     kNewRandomAccessFile,
                     error_code);
}

Status ChromiumEnvStdio::NewWritableFile(const std::string& fname,
                                         WritableFile** result) {
  *result = NULL;
  FILE* f = fopen_internal(fname.c_str(), "wb");
  if (f == NULL) {
    int saved_errno = errno;
    RecordErrorAt(kNewWritableFile);
    return MakeIOError(
        fname, strerror(saved_errno), kNewWritableFile, saved_errno);
  } else {
    *result = new ChromiumWritableFile(fname, f, this, this, make_backup_);
    return Status::OK();
  }
}

#if defined(OS_WIN)
base::File::Error ChromiumEnvStdio::GetDirectoryEntries(
    const base::FilePath& dir_param,
    std::vector<base::FilePath>* result) const {
  result->clear();
  base::FilePath dir_filepath = dir_param.Append(FILE_PATH_LITERAL("*"));
  WIN32_FIND_DATA find_data;
  HANDLE find_handle = FindFirstFile(dir_filepath.value().c_str(), &find_data);
  if (find_handle == INVALID_HANDLE_VALUE) {
    DWORD last_error = GetLastError();
    if (last_error == ERROR_FILE_NOT_FOUND)
      return base::File::FILE_OK;
    return base::File::OSErrorToFileError(last_error);
  }
  do {
    base::FilePath filepath(find_data.cFileName);
    base::FilePath::StringType basename = filepath.BaseName().value();
    if (basename == FILE_PATH_LITERAL(".") ||
        basename == FILE_PATH_LITERAL(".."))
      continue;
    result->push_back(filepath.BaseName());
  } while (FindNextFile(find_handle, &find_data));
  DWORD last_error = GetLastError();
  base::File::Error return_value = base::File::FILE_OK;
  if (last_error != ERROR_NO_MORE_FILES)
    return_value = base::File::OSErrorToFileError(last_error);
  FindClose(find_handle);
  return return_value;
}
#else
base::File::Error ChromiumEnvStdio::GetDirectoryEntries(
    const base::FilePath& dir_filepath,
    std::vector<base::FilePath>* result) const {
  const std::string dir_string = FilePathToString(dir_filepath);
  result->clear();
  DIR* dir = opendir(dir_string.c_str());
  if (!dir)
    return base::File::OSErrorToFileError(errno);
  struct dirent dent_buf;
  struct dirent* dent;
  int readdir_result;
  while ((readdir_result = readdir_r(dir, &dent_buf, &dent)) == 0 && dent) {
    if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
      continue;
    result->push_back(ChromiumEnv::CreateFilePath(dent->d_name));
  }
  int saved_errno = errno;
  closedir(dir);
  if (readdir_result != 0)
    return base::File::OSErrorToFileError(saved_errno);
  return base::File::FILE_OK;
}
#endif

Status ChromiumEnvStdio::NewLogger(const std::string& fname, Logger** result) {
  FILE* f = fopen_internal(fname.c_str(), "w");
  if (f == NULL) {
    *result = NULL;
    int saved_errno = errno;
    RecordOSError(kNewLogger, saved_errno);
    return MakeIOError(fname, strerror(saved_errno), kNewLogger, saved_errno);
  } else {
    *result = new ChromiumLogger(f);
    return Status::OK();
  }
}

}  // namespace leveldb_env
