// Copyright 2021 The Chromium OS 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 "fusebox/file_system_fake.h"

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <algorithm>
#include <string>
#include <vector>

#include <base/check.h>
#include <base/check_op.h>
#include <base/logging.h>
#include <base/no_destructor.h>
#include <base/strings/string_piece.h>

#include "fusebox/fuse_file_handles.h"
#include "fusebox/fuse_path_inodes.h"
#include "fusebox/fuse_request.h"
#include "fusebox/make_stat.h"
#include "fusebox/util.h"

namespace {

void ShowStat(const struct stat& stat, const std::string& name = {}) {
  const char* type = S_ISDIR(stat.st_mode) ? "DIR" : "REG";

  LOG(INFO) << " ENTRY: " << name;
  LOG(INFO) << "    ls: " << fusebox::StatModeToString(stat.st_mode);
  LOG(INFO) << "  mode: " << type << std::hex << " " << stat.st_mode;
  LOG(INFO) << "   dev: " << stat.st_dev;
  LOG(INFO) << "   ino: " << stat.st_ino;
  LOG(INFO) << "  size: " << stat.st_size;
  LOG(INFO) << " nlink: " << stat.st_nlink;
  LOG(INFO) << "  rdev: " << stat.st_rdev;
  LOG(INFO) << "   uid: " << stat.st_uid;
  LOG(INFO) << "   gid: " << stat.st_gid;
  LOG(INFO) << " atime: " << stat.st_atime;
  LOG(INFO) << " mtime: " << stat.st_mtime;
  LOG(INFO) << " ctime: " << stat.st_ctime;
}

}  // namespace

namespace fusebox {

static auto& GetInodeTable() {
  static base::NoDestructor<InodeTable> inode_table;
  return *inode_table;
}

static auto& GetDirEntryVector() {
  static base::NoDestructor<std::vector<struct DirEntry>> entry_vector;
  return *entry_vector;
}

FileSystemFake::FileSystemFake() = default;

FileSystemFake::~FileSystemFake() = default;

void FileSystemFake::Init(void* userdata, struct fuse_conn_info*) {
  LOG(INFO) << "Init";
  CHECK(userdata);

  const auto time_now = std::time(nullptr);
  const bool read_only = true;
  struct stat parent;  // parent node: assume `pwd`.
  CHECK_EQ(0, stat(".", &parent));

  struct stat stat = {0};
  stat.st_atime = time_now;
  stat.st_mtime = time_now;
  stat.st_ctime = time_now;

  Node* root = GetInodeTable().Lookup(1);
  stat.st_mode = S_IFDIR | 0777;
  auto root_stat = MakeStat(root->ino, stat, read_only);
  GetInodeTable().SetStat(root->ino, root_stat);
  ShowStat(root_stat, root->name);

  Node* hello = GetInodeTable().Create(1, "hello");
  stat.st_mode = S_IFREG | 0777;
  stat.st_size = strlen("hello\r\n");
  auto hello_stat = MakeStat(hello->ino, stat, read_only);
  GetInodeTable().SetStat(hello->ino, hello_stat);
  ShowStat(hello_stat, hello->name);

  std::vector<struct DirEntry>& entry = GetDirEntryVector();
  entry.push_back({root->ino, ".", root_stat.st_mode});
  entry.push_back({parent.st_ino, "..", parent.st_mode});
  entry.push_back({hello->ino, "hello", hello_stat.st_mode});
}

void FileSystemFake::Lookup(std::unique_ptr<EntryRequest> request,
                            fuse_ino_t parent,
                            const char* name) {
  LOG(INFO) << "Lookup parent " << parent << " name " << name;

  if (request->IsInterrupted())
    return;

  Node* node = GetInodeTable().Lookup(parent, name);
  if (!node) {
    PLOG(ERROR) << " lookup error";
    request->ReplyError(errno);
    return;
  }

  struct stat stat;
  CHECK(GetInodeTable().GetStat(node->ino, &stat));
  CHECK_EQ(stat.st_ino, node->ino);

  const double kEntryTimeoutSeconds = 5.0;
  fuse_entry_param entry = {0};
  entry.ino = node->ino;
  entry.attr = stat;
  entry.attr_timeout = kEntryTimeoutSeconds;
  entry.entry_timeout = kEntryTimeoutSeconds;

  LOG(INFO) << " found ino " << node->ino;
  request->ReplyEntry(entry);
}

void FileSystemFake::GetAttr(std::unique_ptr<AttrRequest> request,
                             fuse_ino_t ino,
                             struct fuse_file_info* fi) {
  LOG(INFO) << "GetAttr ino " << ino;

  if (request->IsInterrupted())
    return;

  Node* node = GetInodeTable().Lookup(ino);
  if (!node) {
    PLOG(ERROR) << " getattr error";
    request->ReplyError(errno);
    return;
  }

  struct stat stat;
  CHECK(GetInodeTable().GetStat(node->ino, &stat));
  CHECK_EQ(stat.st_ino, node->ino);

  const double kStatTimeoutSeconds = 5.0;
  request->ReplyAttr(stat, kStatTimeoutSeconds);
}

void FileSystemFake::OpenDir(std::unique_ptr<OpenRequest> request,
                             fuse_ino_t ino,
                             struct fuse_file_info* fi) {
  LOG(INFO) << "OpenDir ino " << ino;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  Node* node = GetInodeTable().Lookup(ino);
  if (!node) {
    PLOG(ERROR) << " opendir error";
    request->ReplyError(errno);
    return;
  }

  struct stat stat;
  CHECK(GetInodeTable().GetStat(node->ino, &stat));
  CHECK_EQ(stat.st_ino, node->ino);

  if (!S_ISDIR(stat.st_mode)) {
    LOG(ERROR) << " opendir error: ENOTDIR";
    request->ReplyError(ENOTDIR);
    return;
  }

  LOG(INFO) << " " << OpenFlagsToString(fi->flags);
  if ((fi->flags & O_ACCMODE) != O_RDONLY) {
    LOG(ERROR) << " opendir error: EACCES";
    request->ReplyError(EACCES);
    return;
  }

  uint64_t handle = fusebox::OpenFile();
  LOG(INFO) << " opendir fh " << handle;
  request->ReplyOpen(handle);
}

void FileSystemFake::ReadDir(std::unique_ptr<DirEntryRequest> request,
                             fuse_ino_t ino,
                             off_t off,
                             struct fuse_file_info* fi) {
  LOG(INFO) << "ReadDir ino " << ino << " off " << off;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  if (!fusebox::GetFile(fi->fh)) {
    LOG(ERROR) << " readdir error: EBADF";
    request->ReplyError(EBADF);
    return;
  }

  if (off != 0) {
    LOG(INFO) << " readdir done fh " << fi->fh;
    request->ReplyDone();
    return;
  }

  off_t next = 0;
  LOG(INFO) << " readdir fh " << fi->fh;
  for (const auto& entry : GetDirEntryVector()) {
    LOG(INFO) << " entry [" << entry.name << "]";
    CHECK(request->AddEntry(entry, ++next));
  }

  request->ReplyDone();
}

void FileSystemFake::ReleaseDir(std::unique_ptr<OkRequest> request,
                                fuse_ino_t ino,
                                struct fuse_file_info* fi) {
  LOG(INFO) << "ReleaseDir ino " << ino;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  if (!fusebox::GetFile(fi->fh)) {
    LOG(ERROR) << " releasedir error: EBADF";
    request->ReplyError(EBADF);
    return;
  }

  LOG(INFO) << " releasedir fh " << fi->fh;
  fusebox::CloseFile(fi->fh);
  request->ReplyOk();
}

void FileSystemFake::Open(std::unique_ptr<OpenRequest> request,
                          fuse_ino_t ino,
                          struct fuse_file_info* fi) {
  LOG(INFO) << "Open ino " << ino;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  Node* node = GetInodeTable().Lookup(ino);
  if (!node) {
    PLOG(ERROR) << " open error";
    request->ReplyError(errno);
    return;
  }

  struct stat stat;
  CHECK(GetInodeTable().GetStat(node->ino, &stat));
  CHECK_EQ(stat.st_ino, node->ino);

  if (S_ISDIR(stat.st_mode)) {
    LOG(ERROR) << " opendir error: EISDIR";
    request->ReplyError(EISDIR);
    return;
  }

  LOG(INFO) << " " << OpenFlagsToString(fi->flags);
  if ((fi->flags & O_ACCMODE) != O_RDONLY) {
    LOG(ERROR) << " open error: EACCES";
    request->ReplyError(EACCES);
    return;
  }

  uint64_t handle = fusebox::OpenFile();
  LOG(INFO) << " opened fh " << handle;
  request->ReplyOpen(handle);
}

void FileSystemFake::Read(std::unique_ptr<BufferRequest> request,
                          fuse_ino_t ino,
                          size_t size,
                          off_t off,
                          struct fuse_file_info* fi) {
  LOG(INFO) << "Read ino " << ino << " off " << off << " size " << size;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  if (!fusebox::GetFile(fi->fh)) {
    LOG(ERROR) << " read error: EBADF";
    request->ReplyError(EBADF);
    return;
  }

  struct stat stat;
  CHECK(GetInodeTable().GetStat(ino, &stat));
  CHECK_EQ(stat.st_ino, ino);

  if (S_ISDIR(stat.st_mode)) {
    LOG(ERROR) << " opendir error: EISDIR";
    request->ReplyError(EISDIR);
    return;
  }

  const std::string data("hello\r\n");
  LOG(INFO) << " read fh " << fi->fh;

  const auto get_data_slice = [&data, &off, &size]() {
    auto* source = data.data();
    auto length = data.size();
    if (off < length)
      return base::StringPiece(source + off, std::min(length - off, size));
    return base::StringPiece();
  };

  auto slice = get_data_slice();
  request->ReplyBuffer(slice.data(), slice.size());
}

void FileSystemFake::Release(std::unique_ptr<OkRequest> request,
                             fuse_ino_t ino,
                             struct fuse_file_info* fi) {
  LOG(INFO) << "Release ino " << ino;
  CHECK(fi);

  if (request->IsInterrupted())
    return;

  if (!fusebox::GetFile(fi->fh)) {
    LOG(ERROR) << " release error: EBADF";
    request->ReplyError(EBADF);
    return;
  }

  LOG(INFO) << " release fh " << fi->fh;
  fusebox::CloseFile(fi->fh);
  request->ReplyOk();
}

}  // namespace fusebox
