// Copyright 2017 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 "virtual_file_provider/fuse_main.h"

#include <algorithm>
#include <iterator>
#include <string>
#include <utility>

#include <fuse/fuse.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/stringprintf.h>

#include "virtual_file_provider/operation_throttle.h"
#include "virtual_file_provider/util.h"

namespace virtual_file_provider {

namespace {

constexpr char kFileSystemName[] = "virtual-file-provider";

// Maximum number of operations running at the same time.
constexpr int kMaxOperationCount = 1024;

struct FusePrivateData {
  FuseMainDelegate* delegate;
  OperationThrottle* operation_throttle;
};

FuseMainDelegate* GetDelegate() {
  return static_cast<FusePrivateData*>(fuse_get_context()->private_data)
      ->delegate;
}

OperationThrottle* GetOperationThrottle() {
  return static_cast<FusePrivateData*>(fuse_get_context()->private_data)
      ->operation_throttle;
}

int GetAttr(const char* path, struct stat* stat) {
  // Everything except the root is a file.
  if (path == std::string("/")) {
    stat->st_mode = S_IFDIR | S_IXGRP;
    stat->st_nlink = 2;
  } else {
    DCHECK_EQ('/', path[0]);
    // File name is the ID.
    std::string id(path + 1);

    const int64_t size = GetDelegate()->GetSize(id);
    if (size < 0) {
      LOG(ERROR) << "Invalid ID " << id;
      return -ENOENT;
    }
    stat->st_mode = S_IFREG | S_IRGRP;
    stat->st_nlink = 1;
    stat->st_size = size;
  }
  return 0;
}

int Open(const char* path, struct fuse_file_info* fi) {
  DCHECK_EQ('/', path[0]);
  // File name is the ID.
  const std::string id(path + 1);

  const int64_t file_size = GetDelegate()->GetSize(id);
  if (file_size < 0) {
    LOG(ERROR) << "Invalid ID " << id;
    return -ENOENT;
  }

  return 0;
}

int Read(const char* path,
         char* buf,
         size_t size,
         off_t off,
         struct fuse_file_info* fi) {
  auto operation_reference = GetOperationThrottle()->StartOperation();

  DCHECK_EQ('/', path[0]);
  // File name is the ID.
  std::string id(path + 1);

  // Adjust the size to avoid issuing unnecessary read requests.
  const int64_t file_size = GetDelegate()->GetSize(id);
  if (file_size < 0) {
    LOG(ERROR) << "Invalid ID " << id;
    return -EIO;
  }
  size = std::min(static_cast<int64_t>(size), file_size - off);
  if (size <= 0) {
    return 0;
  }

  // Create a pipe to receive data from chrome. By using pipe instead of D-Bus
  // to receive data, we can reliably avoid deadlock at read(), provided chrome
  // doesn't leak the file descriptor of the write end.
  int fds[2] = {-1, -1};
  if (pipe(fds) != 0) {
    PLOG(ERROR) << "pipe() failed.";
    return -EIO;
  }
  base::ScopedFD read_end(fds[0]), write_end(fds[1]);

  // Send read request to chrome with the write end of the pipe.
  GetDelegate()->HandleReadRequest(id, off, size, std::move(write_end));

  // Read the data from the read end of the pipe.
  size_t result = 0;
  while (result < size) {
    ssize_t r = HANDLE_EINTR(read(read_end.get(), buf + result, size - result));
    if (r < 0) {
      return -EIO;
    }
    if (r == 0) {
      break;
    }
    result += r;
  }
  return result;
}

int Release(const char* path, struct fuse_file_info* fi) {
  DCHECK_EQ('/', path[0]);
  // File name is the ID.
  std::string id(path + 1);

  GetDelegate()->NotifyIdReleased(id);
  return 0;
}

int ReadDir(const char* path,
            void* buf,
            fuse_fill_dir_t filler,
            off_t offset,
            struct fuse_file_info* fi) {
  filler(buf, ".", nullptr, 0);
  filler(buf, "..", nullptr, 0);
  return 0;
}

void* Init(struct fuse_conn_info* conn) {
  CHECK(ClearCapabilities());
  // FUSE will overwrite the context's private_data with the return value.
  // Just return the current private_data.
  return fuse_get_context()->private_data;
}

}  // namespace

int FuseMain(const base::FilePath& mount_path,
             FuseMainDelegate* delegate,
             base::Optional<uid_t> userId,
             base::Optional<gid_t> groupId) {
  std::string mount_options = "noexec";  // disallow code execution
  if (userId || groupId) {
    // allow others to access files
    mount_options.append(",allow_other");
    if (userId) {
      mount_options.append(base::StringPrintf(",uid=%u", userId.value()));
    }
    if (groupId) {
      mount_options.append(base::StringPrintf(",gid=%u", groupId.value()));
    }
  }
  const char* fuse_argv[] = {
      kFileSystemName,
      mount_path.value().c_str(),
      "-f",  // "-f" for foreground.
      "-o",
      mount_options.c_str(),
  };
  constexpr struct fuse_operations operations = {
      .getattr = GetAttr,
      .open = Open,
      .read = Read,
      .release = Release,
      .readdir = ReadDir,
      .init = Init,
  };
  OperationThrottle operation_throttle(kMaxOperationCount);
  FusePrivateData private_data;
  private_data.delegate = delegate;
  private_data.operation_throttle = &operation_throttle;
  return fuse_main(std::size(fuse_argv), const_cast<char**>(fuse_argv),
                   &operations, &private_data);
}

}  // namespace virtual_file_provider
