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

// for S_IF*
#define _XOPEN_SOURCE
#include "src/storage/minfs/host.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <lib/syslog/cpp/macros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/assert.h>

#include <limits>
#include <memory>
#include <string_view>
#include <type_traits>
#include <utility>

#include <fbl/ref_ptr.h>

#include "src/lib/storage/vfs/cpp/vfs.h"
#include "src/lib/storage/vfs/cpp/vfs_types.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/minfs.h"
#include "src/storage/minfs/minfs_private.h"

namespace {

zx_status_t do_stat(fbl::RefPtr<fs::Vnode> vn, struct stat* s) {
  fs::VnodeAttributes a;
  zx_status_t status = vn->GetAttributes(&a);
  if (status == ZX_OK) {
    memset(s, 0, sizeof(struct stat));
    s->st_mode = static_cast<mode_t>(a.mode);
    s->st_size = a.content_size;
    s->st_ino = a.inode;
    s->st_ctime = a.creation_time;
    s->st_mtime = a.modification_time;
  }
  return status;
}

struct HostFile {
  fbl::RefPtr<fs::Vnode> vn;
  uint64_t off = 0;
  fs::VdirCookie dircookie;
};

constexpr int kMaxFd = 64;

static HostFile fdtab[kMaxFd];

constexpr int kFdMagic = 0x45AB0000;

HostFile* file_get(int fd) {
  if ((fd & 0xFFFF0000) != kFdMagic) {
    return nullptr;
  }
  fd &= 0x0000FFFF;
  if ((fd < 0) || (fd >= kMaxFd)) {
    return nullptr;
  }
  if (fdtab[fd].vn == nullptr) {
    return nullptr;
  }
  return fdtab + fd;
}

int status_to_errno(zx_status_t status) {
  switch (status) {
    case ZX_OK:
      return 0;
    case ZX_ERR_FILE_BIG:
      return EFBIG;
    case ZX_ERR_NO_SPACE:
      return ENOSPC;
    case ZX_ERR_ALREADY_EXISTS:
      return EEXIST;
    default:
      return EIO;
  }
}

#define FAIL(err)          \
  do {                     \
    errno = (err);         \
    return errno ? -1 : 0; \
  } while (0)
#define STATUS(status) FAIL(status_to_errno(status))

// Ensure the order of these global destructors are ordered.
// TODO(planders): Host-side tools should avoid using globals.
struct FakeFs {
  std::unique_ptr<fs::Vfs> fake_vfs = nullptr;
  fbl::RefPtr<minfs::VnodeMinfs> fake_root = nullptr;  // Must be destroyed before fake_vfs.
} fake_fs;

}  // namespace

int emu_mkfs(const char* path) {
  fbl::unique_fd fd(open(path, O_RDWR));
  if (!fd) {
    FX_LOGS(ERROR) << "error: could not open path " << path;
    return -1;
  }

  struct stat s;
  if (fstat(fd.get(), &s) < 0) {
    FX_LOGS(ERROR) << "error: minfs could not find end of file/device";
    return -1;
  }

  off_t size = s.st_size / minfs::kMinfsBlockSize;

  std::unique_ptr<minfs::Bcache> bc;
  zx_status_t status = minfs::Bcache::Create(std::move(fd), static_cast<uint32_t>(size), &bc);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "error: cannot create block cache: " << status;
    return -1;
  }

  return Mkfs(bc.get());
}

int emu_mount_bcache(std::unique_ptr<minfs::Bcache> bc) {
  zx_status_t status = minfs::Mount(std::move(bc), minfs::MountOptions(), &fake_fs.fake_root);
  if (status != ZX_OK) {
    return -1;
  }
  fake_fs.fake_vfs.reset(fake_fs.fake_root->Vfs());
  return 0;
}

int emu_create_bcache(const char* path, std::unique_ptr<minfs::Bcache>* out_bc) {
  fbl::unique_fd fd(open(path, O_RDWR));
  if (!fd) {
    FX_LOGS(ERROR) << "error: could not open path " << path;
    return -1;
  }

  struct stat s;
  if (fstat(fd.get(), &s) < 0) {
    FX_LOGS(ERROR) << "error: minfs could not find end of file/device";
    return 0;
  }

  off_t size = s.st_size / minfs::kMinfsBlockSize;

  std::unique_ptr<minfs::Bcache> bc;
  zx_status_t status = minfs::Bcache::Create(std::move(fd), static_cast<uint32_t>(size), &bc);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "error: cannot create block cache: " << status;
    return -1;
  }

  *out_bc = std::move(bc);
  return 0;
}

int emu_mount(const char* path) {
  std::unique_ptr<minfs::Bcache> bc;
  if (emu_create_bcache(path, &bc) != 0) {
    return -1;
  }
  return emu_mount_bcache(std::move(bc));
}

int emu_get_used_resources(const char* path, uint64_t* out_data_size, uint64_t* out_inodes,
                           uint64_t* out_used_size) {
  std::unique_ptr<minfs::Bcache> bc;
  if (emu_create_bcache(path, &bc) != 0) {
    return -1;
  }
  if (minfs::UsedDataSize(bc, out_data_size) != ZX_OK) {
    return -1;
  }

  if (minfs::UsedInodes(bc, out_inodes) != ZX_OK) {
    return -1;
  }

  if (minfs::UsedSize(bc, out_used_size) != ZX_OK) {
    return -1;
  }

  return 0;
}

bool emu_is_mounted() { return fake_fs.fake_root != nullptr; }

// Converts POSIX open() flags to |VnodeConnectionOptions|.
fs::VnodeConnectionOptions fdio_flags_to_connection_options(uint32_t flags) {
  fs::VnodeConnectionOptions options;

  switch (flags & O_ACCMODE) {
    case O_RDONLY:
      options.rights.read = true;
      break;
    case O_WRONLY:
      options.rights.write = true;
      break;
    case O_RDWR:
      options.rights.read = true;
      options.rights.write = true;
      break;
  }
#ifdef O_PATH
  if (flags & O_PATH) {
    options.flags.node_reference = true;
  }
#endif
#ifdef O_DIRECTORY
  if (flags & O_DIRECTORY) {
    options.flags.directory = true;
  }
#endif
  if (flags & O_CREAT) {
    options.flags.create = true;
  }
  if (flags & O_EXCL) {
    options.flags.fail_if_exists = true;
  }
  if (flags & O_TRUNC) {
    options.flags.truncate = true;
  }
  if (flags & O_APPEND) {
    options.flags.append = true;
  }

  return options;
}

int emu_open(const char* path, int flags, mode_t mode) {
  // TODO: fdtab lock
  ZX_DEBUG_ASSERT_MSG(!host_path(path), "'emu_' functions can only operate on target paths");
  if (flags & O_APPEND) {
    errno = ENOTSUP;
    return -1;
  }
  for (int fd = 0; fd < kMaxFd; fd++) {
    if (fdtab[fd].vn == nullptr) {
      std::string_view str(path + PREFIX_SIZE);
      fs::VnodeConnectionOptions options = fdio_flags_to_connection_options(flags);
      auto result =
          fake_fs.fake_vfs->Open(fake_fs.fake_root, str, options, fs::Rights::ReadWrite(), mode);
      if (result.is_error()) {
        STATUS(result.error());
      }
      fdtab[fd].vn = fbl::RefPtr<fs::Vnode>::Downcast(result.ok().vnode);
      return fd | kFdMagic;
    }
  }
  FAIL(EMFILE);
}

int emu_close(int fd) {
  // TODO: fdtab lock
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  f->vn->Close();
  f->vn.reset();
  f->off = 0;
  f->dircookie = fs::VdirCookie();
  return 0;
}

ssize_t emu_write(int fd, const void* buf, size_t count) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  size_t actual = 0;
  zx_status_t status = f->vn->Write(buf, count, f->off, &actual);
  if (status == ZX_OK) {
    f->off += actual;
    ZX_DEBUG_ASSERT(actual <= std::numeric_limits<ssize_t>::max());
    return static_cast<ssize_t>(actual);
  }

  ZX_DEBUG_ASSERT(status < 0);
  STATUS(status);
}

ssize_t emu_pwrite(int fd, const void* buf, size_t count, off_t off) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  size_t actual;
  zx_status_t status = f->vn->Write(buf, count, off, &actual);
  if (status == ZX_OK) {
    ZX_DEBUG_ASSERT(actual <= std::numeric_limits<ssize_t>::max());
    return static_cast<ssize_t>(actual);
  }

  ZX_DEBUG_ASSERT(status < 0);
  STATUS(status);
}

ssize_t emu_read(int fd, void* buf, size_t count) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  size_t actual = 0;
  zx_status_t status = f->vn->Read(buf, count, f->off, &actual);
  if (status == ZX_OK) {
    f->off += actual;
    ZX_DEBUG_ASSERT(actual <= std::numeric_limits<ssize_t>::max());
    return static_cast<ssize_t>(actual);
  }
  ZX_DEBUG_ASSERT(status < 0);
  STATUS(status);
}

ssize_t emu_pread(int fd, void* buf, size_t count, off_t off) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  size_t actual;
  zx_status_t status = f->vn->Read(buf, count, off, &actual);
  if (status == ZX_OK) {
    ZX_DEBUG_ASSERT(actual <= std::numeric_limits<ssize_t>::max());
    return static_cast<ssize_t>(actual);
  }
  ZX_DEBUG_ASSERT(status < 0);
  STATUS(status);
}

int emu_ftruncate(int fd, off_t len) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  int r = f->vn->Truncate(len);
  return r < 0 ? -1 : r;
}

off_t emu_lseek(int fd, off_t offset, int whence) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }

  uint64_t old = f->off;

  switch (whence) {
    case SEEK_SET: {
      if (offset < 0) {
        FAIL(EINVAL);
      }
      f->off = offset;
      break;
    }
    case SEEK_END: {
      fs::VnodeAttributes a;
      if (f->vn->GetAttributes(&a)) {
        FAIL(EINVAL);
      }
      old = a.content_size;
      __FALLTHROUGH;
    }
    case SEEK_CUR: {
      uint64_t n = old + offset;
      if (offset < 0) {
        if (n >= old) {
          FAIL(EINVAL);
        }
      } else {
        if (n < old) {
          FAIL(EINVAL);
        }
      }
      f->off = n;
      break;
    }
    default: {
      FAIL(EINVAL);
    }
  }
  return f->off;
}

int emu_fstat(int fd, struct stat* s) {
  HostFile* f = file_get(fd);
  if (f == nullptr) {
    return -1;
  }
  STATUS(do_stat(f->vn, s));
}

int emu_stat(const char* fn, struct stat* s) {
  ZX_DEBUG_ASSERT_MSG(!host_path(fn), "'emu_' functions can only operate on target paths");
  fbl::RefPtr<fs::Vnode> vn = fake_fs.fake_root;
  fbl::RefPtr<fs::Vnode> cur = fake_fs.fake_root;

  const char* nextpath = nullptr;

  fn += PREFIX_SIZE;
  do {
    while (fn[0] == '/') {
      fn++;
    }
    if (fn[0] == 0) {
      break;
    }
    size_t len = strlen(fn);
    nextpath = strchr(fn, '/');
    if (nextpath != nullptr) {
      len = nextpath - fn;
      nextpath++;
    }
    fbl::RefPtr<fs::Vnode> vn_fs;
    zx_status_t status = cur->Lookup(std::string_view(fn, len), &vn_fs);
    if (status != ZX_OK) {
      return -ENOENT;
    }
    vn = fbl::RefPtr<fs::Vnode>::Downcast(vn_fs);
    cur = vn;
    fn = nextpath;
  } while (nextpath != nullptr);

  zx_status_t status = do_stat(vn, s);
  STATUS(status);
}

constexpr size_t kDirBufSize = 2048;

struct MinDir {
  ~MinDir() {
    if (vn)
      vn->Close();
  }

  uint64_t magic = minfs::kMinfsMagic0;
  fbl::RefPtr<fs::Vnode> vn;
  fs::VdirCookie cookie;
  uint8_t* ptr = nullptr;
  uint8_t data[kDirBufSize] = {0};
  size_t size = 0;
  dirent de = {};
};

int emu_mkdir(const char* path, mode_t mode) {
  ZX_DEBUG_ASSERT_MSG(!host_path(path), "'emu_' functions can only operate on target paths");
  mode = S_IFDIR;
  int fd = emu_open(path, O_CREAT | O_EXCL, S_IFDIR | (mode & 0777));
  if (fd >= 0) {
    emu_close(fd);
    return 0;
  } else {
    return fd;
  }
}

DIR* emu_opendir(const char* name) {
  ZX_DEBUG_ASSERT_MSG(!host_path(name), "'emu_' functions can only operate on target paths");
  std::string_view path(name + PREFIX_SIZE);
  fs::VnodeConnectionOptions options;
  options.rights.read = true;
  options.flags.posix = true;
  auto result =
      fake_fs.fake_vfs->Open(fake_fs.fake_root, path, options, fs::Rights::ReadWrite(), 0);
  if (result.is_error()) {
    return nullptr;
  }
  MinDir* dir = new MinDir();
  dir->vn = fbl::RefPtr<fs::Vnode>::Downcast(result.ok().vnode);
  return reinterpret_cast<DIR*>(dir);
}

dirent* emu_readdir(DIR* dirp) {
  MinDir* dir = reinterpret_cast<MinDir*>(dirp);
  for (;;) {
    if (dir->size >= sizeof(vdirent_t)) {
      vdirent_t* vde = reinterpret_cast<vdirent_t*>(dir->ptr);
      dirent* ent = &dir->de;
      size_t name_len = vde->size;
      size_t entry_len = vde->size + sizeof(vdirent_t);
      ZX_DEBUG_ASSERT(dir->size >= entry_len);
      memcpy(ent->d_name, vde->name, name_len);
      ent->d_name[name_len] = '\0';
      ent->d_type = vde->type;
      dir->ptr += entry_len;
      dir->size -= entry_len;
      return ent;
    }
    size_t actual = 0;
    zx_status_t status = dir->vn->Readdir(&dir->cookie, &dir->data, kDirBufSize, &actual);
    if (status != ZX_OK || actual == 0) {
      break;
    }
    dir->ptr = dir->data;
    dir->size = actual;
  }
  return nullptr;
}

void emu_rewinddir(DIR* dirp) {
  MinDir* dir = reinterpret_cast<MinDir*>(dirp);
  dir->size = 0;
  dir->ptr = NULL;
  dir->cookie.n = 0;
}

int emu_closedir(DIR* dirp) {
  if (reinterpret_cast<uint64_t*>(dirp)[0] != minfs::kMinfsMagic0) {
    return closedir(dirp);
  }

  MinDir* dir = reinterpret_cast<MinDir*>(dirp);
  delete dir;

  return 0;
}
