// Copyright 2016 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.

#ifndef SRC_STORAGE_MINFS_HOST_H_
#define SRC_STORAGE_MINFS_HOST_H_

#ifdef __Fuchsia__
#error Host-only Header
#endif

#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>

#include <fbl/macros.h>

#include "src/storage/minfs/bcache.h"

#define PATH_PREFIX "::"
#define PREFIX_SIZE 2

// Return "true" if the path refers to a file on the
// host machine. Otherwise, refers to a file within the
// target disk image.
static inline bool host_path(const char* path) {
  if (strncmp(path, PATH_PREFIX, PREFIX_SIZE)) {
    return true;
  }
  return false;
}
int emu_mkfs(const char* path);
int emu_mount(const char* path);
int emu_mount_bcache(std::unique_ptr<minfs::Bcache> bc);
bool emu_is_mounted();
int emu_get_used_resources(const char* path, uint64_t* out_data_size, uint64_t* out_inodes,
                           uint64_t* out_used_size);

int emu_open(const char* path, int flags, mode_t mode);
int emu_close(int fd);

ssize_t emu_write(int fd, const void* buf, size_t count);
ssize_t emu_pwrite(int fd, const void* buf, size_t count, off_t off);
ssize_t emu_read(int fd, void* buf, size_t count);
ssize_t emu_pread(int fd, void* buf, size_t count, off_t off);

int emu_ftruncate(int fd, off_t len);
off_t emu_lseek(int fd, off_t offset, int whence);
int emu_fstat(int fd, struct stat* s);
int emu_stat(const char* fn, struct stat* s);

int emu_mkdir(const char* path, mode_t mode);
DIR* emu_opendir(const char* name);
struct dirent* emu_readdir(DIR* dirp);
void emu_rewinddir(DIR* dirp);
int emu_closedir(DIR* dirp);

// FileWrapper is a wrapper around an open file descriptor,
// which abstracts away the "hostness" or "targetness"
// of the underlying target. Additionally, it provides
// RAII semantics to the underlying file descriptor.
class FileWrapper {
 public:
  constexpr FileWrapper() : hostfile_(false), fd_(0) {}

  // Not copyable or movable
  FileWrapper(const FileWrapper&) = delete;
  FileWrapper& operator=(const FileWrapper&) = delete;
  FileWrapper(FileWrapper&&) = delete;
  FileWrapper& operator=(FileWrapper&&) = delete;

  ~FileWrapper() { Close(); }

  static int Open(const char* path, int flags, mode_t mode, FileWrapper* out) {
    int r;
    if (host_path(path)) {
      out->hostfile_ = true;
      r = open(path, flags, mode);
    } else {
      out->hostfile_ = false;
      r = emu_open(path, flags, mode);
    }
    if (r > 0) {
      out->fd_ = r;
    }
    return r;
  }
  int Close() {
    if (fd_ == 0) {
      return -1;
    }
    int r = hostfile_ ? close(fd_) : emu_close(fd_);
    fd_ = 0;
    return r;
  }
  ssize_t Read(void* buf, size_t count) {
    return hostfile_ ? read(fd_, buf, count) : emu_read(fd_, buf, count);
  }
  ssize_t Write(void* buf, size_t count) {
    return hostfile_ ? write(fd_, buf, count) : emu_write(fd_, buf, count);
  }

 private:
  bool hostfile_;
  int fd_{};
};

// DirWrapper is a wrapper around an open directory,
// which abstracts away the "hostness" or "targetness"
// of the underlying target. Additionally, it provides
// RAII semantics to the underlying directory.
class DirWrapper {
 public:
  constexpr DirWrapper() : hostdir_(false), dir_(NULL) {}

  // Not copyable or movable
  DirWrapper(const DirWrapper&) = delete;
  DirWrapper& operator=(const DirWrapper&) = delete;
  DirWrapper(DirWrapper&&) = delete;
  DirWrapper& operator=(DirWrapper&&) = delete;

  ~DirWrapper() { Close(); }

  static int Make(const char* path, mode_t mode) {
    return host_path(path) ? mkdir(path, mode) : emu_mkdir(path, mode);
  }
  static int Open(const char* path, DirWrapper* out) {
    if (host_path(path)) {
      out->hostdir_ = true;
      out->dir_ = opendir(path);
    } else {
      out->hostdir_ = false;
      out->dir_ = emu_opendir(path);
    }
    return out->dir_ == NULL ? -1 : 0;
  }
  int Close() { return hostdir_ ? closedir(dir_) : emu_closedir(dir_); }
  struct dirent* ReadDir() { return hostdir_ ? readdir(dir_) : emu_readdir(dir_); }

 private:
  bool hostdir_;
  DIR* dir_;
};

#endif  // SRC_STORAGE_MINFS_HOST_H_
