// Copyright (c) 2011 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.

// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <deque>
#include <set>
#include "leveldb/env.h"
#include "leveldb/slice.h"
#include "port/port.h"
#include "port/thread_annotations.h"
#include "util/logging.h"
#include "util/mutexlock.h"

namespace leveldb {

namespace {

// Equivalent modes for open to fopen "r", "w" and "a" modes respectively.
constexpr int kReadMode = O_RDONLY;
constexpr int kWriteMode = O_WRONLY | O_CREAT | O_TRUNC;
constexpr int kAppendMode = O_WRONLY | O_CREAT | O_APPEND;

DIR* OpenDirAt(int root_fd, const char* path) {
  int fd = openat(root_fd, path, kReadMode);
  if (fd < 0) {
    return nullptr;
  }
  return fdopendir(fd);
}

FILE* FOpenAt(int root_fd, const char*  path, int mode) {
  const char* fopen_mode = nullptr;
  switch (mode) {
    case kReadMode:
      fopen_mode = "r";
      break;
    case kWriteMode:
      fopen_mode = "w";
      break;
    case kAppendMode:
      fopen_mode = "a";
      break;
    default:
      abort();
  }
  int fd = openat(root_fd, path, mode);
  if (fd < 0) {
    return nullptr;
  }
  return fdopen(fd, fopen_mode);
}

class FuchsiaLogger : public Logger {
 private:
  FILE* file_;
  uint64_t (*gettid_)();  // Return the thread id for the current thread
 public:
  FuchsiaLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
  virtual ~FuchsiaLogger() {
    fclose(file_);
  }
  virtual void Logv(const char* format, va_list ap) {
    const uint64_t thread_id = (*gettid_)();

    // We try twice: the first time with a fixed-size stack allocated buffer,
    // and the second time with a much larger dynamically allocated buffer.
    char buffer[500];
    for (int iter = 0; iter < 2; iter++) {
      char* base;
      int bufsize;
      if (iter == 0) {
        bufsize = sizeof(buffer);
        base = buffer;
      } else {
        bufsize = 30000;
        base = new char[bufsize];
      }
      char* p = base;
      char* limit = base + bufsize;

      struct timeval now_tv;
      gettimeofday(&now_tv, nullptr);
      p += snprintf(p, limit - p,
                    "%06d %llx ",
                    static_cast<int>(now_tv.tv_usec),
                    static_cast<long long unsigned int>(thread_id));

      // Print the message
      if (p < limit) {
        va_list backup_ap;
        va_copy(backup_ap, ap);
        p += vsnprintf(p, limit - p, format, backup_ap);
        va_end(backup_ap);
      }

      // Truncate to available space if necessary
      if (p >= limit) {
        if (iter == 0) {
          continue;       // Try again with larger buffer
        } else {
          p = limit - 1;
        }
      }

      // Add newline if necessary
      if (p == base || p[-1] != '\n') {
        *p++ = '\n';
      }

      assert(p <= limit);
      fwrite(base, 1, p - base, file_);
      fflush(file_);
      if (base != buffer) {
        delete[] base;
      }
      break;
    }
  }
};

static Status FuchsiaError(const std::string& context, int err_number) {
  if (err_number == ENOENT) {
    return Status::NotFound(context, strerror(err_number));
  } else {
    return Status::IOError(context, strerror(err_number));
  }
}

class FuchsiaSequentialFile: public SequentialFile {
 private:
  std::string filename_;
  FILE* file_;

 public:
  FuchsiaSequentialFile(const std::string& fname, FILE* f)
      : filename_(fname), file_(f) { }
  virtual ~FuchsiaSequentialFile() { 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 = FuchsiaError(filename_, errno);
      }
    }
    return s;
  }

  virtual Status Skip(uint64_t n) {
    if (fseek(file_, n, SEEK_CUR)) {
      return FuchsiaError(filename_, errno);
    }
    return Status::OK();
  }
};

// This is typically less efficient that mmap-ing the file, but file-backed mmap
// is not currently available on Fuchsia.
// TODO(ppi): when mmaping files is possible of Fuchsia, bring in mmap-based
// impl.
class FuchsiaRandomAccessFile: public RandomAccessFile {
 private:
  std::string filename_;
  int fd_;

 public:
  FuchsiaRandomAccessFile(const std::string& fname, int fd)
      : filename_(fname), fd_(fd) { }
  virtual ~FuchsiaRandomAccessFile() { close(fd_); }

  virtual Status Read(uint64_t offset, size_t n, Slice* result,
                      char* scratch) const {
    Status s;
    ssize_t r = pread(fd_, scratch, n, static_cast<off_t>(offset));
    *result = Slice(scratch, (r < 0) ? 0 : r);
    if (r < 0) {
      // An error: return a non-ok status
      s = FuchsiaError(filename_, errno);
    }
    return s;
  }
};

class FuchsiaWritableFile : public WritableFile {
 private:
  int root_fd_;
  std::string filename_;
  FILE* file_;

 public:
  FuchsiaWritableFile(int root_fd, const std::string& fname, FILE* f)
      : root_fd_(root_fd), filename_(fname), file_(f) { }

  ~FuchsiaWritableFile() {
    if (file_ != nullptr) {
      // Ignoring any potential errors
      fclose(file_);
    }
  }

  virtual Status Append(const Slice& data) {
    size_t r = fwrite_unlocked(data.data(), 1, data.size(), file_);
    if (r != data.size()) {
      return FuchsiaError(filename_, errno);
    }
    return Status::OK();
  }

  virtual Status Close() {
    Status result;
    if (fclose(file_) != 0) {
      result = FuchsiaError(filename_, errno);
    }
    file_ = nullptr;
    return result;
  }

  virtual Status Flush() {
    if (fflush_unlocked(file_) != 0) {
      return FuchsiaError(filename_, errno);
    }
    return Status::OK();
  }

  Status SyncDirIfManifest() {
    const char* f = filename_.c_str();
    const char* sep = strrchr(f, '/');
    Slice basename;
    std::string dir;
    if (sep == nullptr) {
      dir = ".";
      basename = f;
    } else {
      dir = std::string(f, sep - f);
      basename = sep + 1;
    }
    Status s;
    if (basename.starts_with("MANIFEST")) {
      int fd = openat(root_fd_, dir.c_str(), kReadMode);
      if (fd < 0) {
        s = FuchsiaError(dir, errno);
      } else {
        if (fsync(fd) < 0) {
          s = FuchsiaError(dir, errno);
        }
        close(fd);
      }
    }
    return s;
  }

  virtual Status Sync() {
    // Ensure new files referred to by the manifest are in the filesystem.
    Status s = SyncDirIfManifest();
    if (!s.ok()) {
      return s;
    }
    if (fflush_unlocked(file_) != 0 ||
        fdatasync(fileno(file_)) != 0) {
      s = Status::IOError(filename_, strerror(errno));
    }
    return s;
  }
};

class FuchsiaFileLock : public FileLock {
 public:
  std::string name_;
};

// Set of locked files. This is used to guard against multiple uses from one
// process.
class LockTable {
 private:
  port::Mutex mu_;
  std::set<std::string> locked_files_ GUARDED_BY(mu_);
 public:
  bool Insert(const std::string& fname) LOCKS_EXCLUDED(mu_) {
    MutexLock l(&mu_);
    return locked_files_.insert(fname).second;
  }
  void Remove(const std::string& fname) LOCKS_EXCLUDED(mu_) {
    MutexLock l(&mu_);
    locked_files_.erase(fname);
  }
};

class FuchsiaEnv : public Env {
 public:
  FuchsiaEnv(int root_fd);

  virtual ~FuchsiaEnv() {
    if (this == Env::Default()) {
      char msg[] = "Destroying Env::Default()\n";
      fwrite(msg, 1, sizeof(msg), stderr);
      abort();
    }
  }

  virtual Status NewSequentialFile(const std::string& fname,
                                   SequentialFile** result) {
    FILE* f = FOpenAt(root_fd_, fname.c_str(), kReadMode);
    if (f == nullptr) {
      *result = nullptr;
      return FuchsiaError(fname, errno);
    } else {
      *result = new FuchsiaSequentialFile(fname, f);
      return Status::OK();
    }
  }

  virtual Status NewRandomAccessFile(const std::string& fname,
                                     RandomAccessFile** result) {
    *result = nullptr;
    Status s;
    int fd = openat(root_fd_, fname.c_str(), kReadMode);
    if (fd < 0) {
      s = FuchsiaError(fname, errno);
    } else {
      *result = new FuchsiaRandomAccessFile(fname, fd);
    }
    return s;
  }

  virtual Status NewWritableFile(const std::string& fname,
                                 WritableFile** result) {
    Status s;
    FILE* f = FOpenAt(root_fd_, fname.c_str(), kWriteMode);
    if (f == nullptr) {
      *result = nullptr;
      s = FuchsiaError(fname, errno);
    } else {
      *result = new FuchsiaWritableFile(root_fd_, fname, f);
    }
    return s;
  }

  virtual Status NewAppendableFile(const std::string& fname,
                                   WritableFile** result) {
    Status s;
    FILE* f = FOpenAt(root_fd_, fname.c_str(), kAppendMode);
    if (f == nullptr) {
      *result = nullptr;
      s = FuchsiaError(fname, errno);
    } else {
      *result = new FuchsiaWritableFile(root_fd_, fname, f);
    }
    return s;
  }

  virtual bool FileExists(const std::string& fname) {
    return faccessat(root_fd_, fname.c_str(), F_OK, 0) == 0;
  }

  virtual Status GetChildren(const std::string& dir,
                             std::vector<std::string>* result) {
    result->clear();
    DIR* d = OpenDirAt(root_fd_, dir.c_str());
    if (d == nullptr) {
      return FuchsiaError(dir, errno);
    }
    struct dirent* entry;
    while ((entry = readdir(d)) != nullptr) {
      result->push_back(entry->d_name);
    }
    closedir(d);
    return Status::OK();
  }

  virtual Status DeleteFile(const std::string& fname) {
    Status result;
    if (unlinkat(root_fd_, fname.c_str(), 0) != 0) {
      result = FuchsiaError(fname, errno);
    }
    return result;
  }

  virtual Status CreateDir(const std::string& name) {
    Status result;
    if (mkdirat(root_fd_, name.c_str(), 0755) != 0) {
      result = FuchsiaError(name, errno);
    }
    return result;
  }

  virtual Status DeleteDir(const std::string& name) {
    Status result;
    if (unlinkat(root_fd_, name.c_str(), AT_REMOVEDIR) != 0) {
      result = FuchsiaError(name, errno);
    }
    return result;
  }

  virtual Status GetFileSize(const std::string& fname, uint64_t* size) {
    Status s;
    struct stat sbuf;
    if (fstatat(root_fd_, fname.c_str(), &sbuf, 0) != 0) {
      *size = 0;
      s = FuchsiaError(fname, errno);
    } else {
      *size = sbuf.st_size;
    }
    return s;
  }

  virtual Status RenameFile(const std::string& src, const std::string& target) {
    Status result;
    if (renameat(root_fd_, src.c_str(), root_fd_, target.c_str()) != 0) {
      result = FuchsiaError(src, errno);
    }
    return result;
  }

  // Our implementation uses the |locks_| table to guard against creating
  // multiple databases backed by the same file within one process. This does
  // not guard against multiple processes using the same file concurrently.
  virtual Status LockFile(const std::string& fname, FileLock** lock) {
    *lock = nullptr;
    Status result;
    if (!locks_.Insert(fname)) {
      result = Status::IOError("lock " + fname, "already held by process");
    } else {
      FuchsiaFileLock* my_lock = new FuchsiaFileLock;
      my_lock->name_ = fname;
      *lock = my_lock;
    }
    return result;
  }

  virtual Status UnlockFile(FileLock* lock) {
    FuchsiaFileLock* my_lock = reinterpret_cast<FuchsiaFileLock*>(lock);
    Status result;
    locks_.Remove(my_lock->name_);
    delete my_lock;
    return result;
  }

  virtual void Schedule(void (*function)(void*), void* arg);

  virtual void StartThread(void (*function)(void* arg), void* arg);

  virtual Status GetTestDirectory(std::string* result) {
    const char* env = getenv("TEST_TMPDIR");
    if (env && env[0] != '\0') {
      *result = env;
    } else {
      char buf[100];
      snprintf(buf, sizeof(buf), "/tmp/leveldbtest-%d", int(geteuid()));
      *result = buf;
    }
    // Directory may already exist
    CreateDir(*result);
    return Status::OK();
  }

  static uint64_t gettid() {
    pthread_t tid = pthread_self();
    uint64_t thread_id = 0;
    memcpy(&thread_id, &tid, std::min(sizeof(thread_id), sizeof(tid)));
    return thread_id;
  }

  virtual Status NewLogger(const std::string& fname, Logger** result) {
    FILE* f = FOpenAt(root_fd_, fname.c_str(), kWriteMode);
    if (f == nullptr) {
      *result = nullptr;
      return FuchsiaError(fname, errno);
    } else {
      *result = new FuchsiaLogger(f, &FuchsiaEnv::gettid);
      return Status::OK();
    }
  }

  virtual uint64_t NowMicros() {
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
  }

  virtual void SleepForMicroseconds(int micros) {
    usleep(micros);
  }

 private:
  void PthreadCall(const char* label, int result) {
    if (result != 0) {
      fprintf(stderr, "pthread %s: %s\n", label, strerror(result));
      abort();
    }
  }

  // BGThread() is the body of the background thread
  void BGThread();
  static void* BGThreadWrapper(void* arg) {
    reinterpret_cast<FuchsiaEnv*>(arg)->BGThread();
    return nullptr;
  }

  int root_fd_;

  pthread_mutex_t mu_;
  pthread_cond_t bgsignal_;
  pthread_t bgthread_;
  bool started_bgthread_;

  // Entry per Schedule() call
  struct BGItem { void* arg; void (*function)(void*); };
  typedef std::deque<BGItem> BGQueue;
  BGQueue queue_;

  LockTable locks_;
};

FuchsiaEnv::FuchsiaEnv(int root_fd) : root_fd_(root_fd), started_bgthread_(false) {
  if (root_fd_ != AT_FDCWD && root_fd_ < 0) {
    abort();
  }
  PthreadCall("mutex_init", pthread_mutex_init(&mu_, nullptr));
  PthreadCall("cvar_init", pthread_cond_init(&bgsignal_, nullptr));
}

void FuchsiaEnv::Schedule(void (*function)(void*), void* arg) {
  PthreadCall("lock", pthread_mutex_lock(&mu_));

  // Start background thread if necessary
  if (!started_bgthread_) {
    started_bgthread_ = true;
    PthreadCall(
        "create thread",
        pthread_create(&bgthread_, nullptr,  &FuchsiaEnv::BGThreadWrapper, this));
  }

  // If the queue is currently empty, the background thread may currently be
  // waiting.
  if (queue_.empty()) {
    PthreadCall("signal", pthread_cond_signal(&bgsignal_));
  }

  // Add to priority queue
  queue_.push_back(BGItem());
  queue_.back().function = function;
  queue_.back().arg = arg;

  PthreadCall("unlock", pthread_mutex_unlock(&mu_));
}

void FuchsiaEnv::BGThread() {
  while (true) {
    // Wait until there is an item that is ready to run
    PthreadCall("lock", pthread_mutex_lock(&mu_));
    while (queue_.empty()) {
      PthreadCall("wait", pthread_cond_wait(&bgsignal_, &mu_));
    }

    void (*function)(void*) = queue_.front().function;
    void* arg = queue_.front().arg;
    queue_.pop_front();

    PthreadCall("unlock", pthread_mutex_unlock(&mu_));
    (*function)(arg);
  }
}

namespace {
struct StartThreadState {
  void (*user_function)(void*);
  void* arg;
};
}
static void* StartThreadWrapper(void* arg) {
  StartThreadState* state = reinterpret_cast<StartThreadState*>(arg);
  state->user_function(state->arg);
  delete state;
  return nullptr;
}

void FuchsiaEnv::StartThread(void (*function)(void* arg), void* arg) {
  pthread_t t;
  StartThreadState* state = new StartThreadState;
  state->user_function = function;
  state->arg = arg;
  PthreadCall("start thread",
              pthread_create(&t, nullptr,  &StartThreadWrapper, state));
}

}  // namespace

static pthread_once_t once = PTHREAD_ONCE_INIT;
static Env* default_env;

static void InitDefaultEnv() { default_env = new FuchsiaEnv(AT_FDCWD); }

Env* Env::Default() {
  pthread_once(&once, InitDefaultEnv);
  return default_env;
}

std::unique_ptr<Env> MakeFuchsiaEnv(int root_fd) {
  return std::make_unique<FuchsiaEnv>(root_fd);
}

}  // namespace leveldb
