// Copyright 2019 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 "arc/obb-mounter/mount_obb_fuse_main.h"

#include <fuse/fuse.h>
#include <time.h>
#include <utility>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/optional.h>
#include <base/stl_util.h>
#include <base/strings/string_util.h>
#include <base/strings/utf_string_conversions.h>
#include <base/synchronization/lock.h>
#include <brillo/syslog_logging.h>

#include "arc/obb-mounter/volume.h"

namespace {

const mode_t kFileMode = S_IRUSR | S_IRGRP | S_IFREG;
const mode_t kDirMode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IFDIR;

fat::Volume* g_volume = nullptr;

using DirectoryEntry = fat::Volume::DirectoryEntry;

// Uses base::Lock to use FileReader in a thread-safe manner.
class FileReaderThreadSafe {
 public:
  FileReaderThreadSafe(fat::Volume* volume,
                       int64_t start_cluster,
                       int64_t file_size)
    : reader_(volume, start_cluster, file_size) {}
  ~FileReaderThreadSafe() = default;

  int64_t Read(char* buf, int64_t size, int64_t offset) {
    base::AutoLock auto_lock(lock_);
    return reader_.Read(buf, size, offset);
  }

 private:
  fat::Volume::FileReader reader_;
  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(FileReaderThreadSafe);
};

// Converts DirectoryEntry to stat.
void ConvertDirectoryEntryToStat(const DirectoryEntry& entry,
                                 struct stat* stat) {
  if (entry.is_directory) {
    stat->st_mode = kDirMode;
    stat->st_nlink = 2;
  } else {
    stat->st_mode = kFileMode;
    stat->st_nlink = 1;
    stat->st_size = entry.file_size;
  }
  stat->st_mtime = entry.last_modification.ToBaseTime().ToTimeT();
}

// Gets a DirectoryEntry with the given path.
bool GetDirectoryEntry(const base::StringPiece16& path,
                       DirectoryEntry* out) {
  if (path.empty() || path[0] != '/') {
    return false;
  }
  int64_t current_directory_start_sector = g_volume->root_dir_start_sector();
  size_t pos = 1;
  while (true) {
    size_t next_slash = path.find('/', pos);
    if (next_slash == base::StringPiece::npos) {
      next_slash = path.size();
    }
    base::StringPiece16 name(path.data() + pos, next_slash - pos);
    base::Optional<DirectoryEntry> entry;
    if (!g_volume->ReadDirectory(current_directory_start_sector,
                                 base::BindRepeating(
                                     [](const base::StringPiece16& name,
                                        base::Optional<DirectoryEntry>* entry,
                                        const base::StringPiece16& name_in,
                                        const DirectoryEntry& entry_in) {
                                       // TODO(hashimoto): Consider using
                                       // base::i18n::ToLower to be
                                       // case-insensitive for non-ASCII
                                       // characters.
                                       if (base::EqualsCaseInsensitiveASCII(
                                               name, name_in)) {
                                         *entry = entry_in;
                                         return false;
                                       }
                                       return true;
                                     },
                                     name, &entry)) ||
        !entry.has_value()) {
      return false;
    }
    pos = next_slash + 1;
    if (pos >= path.size()) {
      *out = entry.value();
      return true;
    }
    if (!entry->is_directory) {
      return false;
    }
    current_directory_start_sector =
        g_volume->GetClusterStartSector(entry->start_cluster);
  }
}

int fat_getattr(const char* path, struct stat* stat) {
  VLOG(1) << "fat_getattr: " << path;
  if (strcmp(path, "/") == 0) {
    stat->st_mode = kDirMode;
    stat->st_nlink = 2;
    return 0;
  }
  DirectoryEntry entry;
  if (!GetDirectoryEntry(base::UTF8ToUTF16(path), &entry)) {
    return -ENOENT;
  }
  ConvertDirectoryEntryToStat(entry, stat);
  return 0;
}

int fat_open(const char* path, struct fuse_file_info* fi) {
  VLOG(1) << "fat_open: " << path;
  if ((fi->flags & O_ACCMODE) != O_RDONLY) {
    return -EACCES;
  }
  DirectoryEntry entry;
  if (!GetDirectoryEntry(base::UTF8ToUTF16(path), &entry)) {
    return -ENOENT;
  }
  if (entry.is_directory) {
    return -EISDIR;
  }
  fi->keep_cache = 1;
  fi->fh = reinterpret_cast<uint64_t>(
      new FileReaderThreadSafe(g_volume, entry.start_cluster, entry.file_size));
  return 0;
}

int fat_read(const char* path,
             char* buf,
             size_t size,
             off_t off,
             struct fuse_file_info* fi) {
  int64_t result =
      reinterpret_cast<FileReaderThreadSafe*>(fi->fh)->Read(buf, size, off);
  if (result < 0) {
    return -EIO;
  }
  return result;
}

int fat_release(const char* path, struct fuse_file_info* fi) {
  delete reinterpret_cast<FileReaderThreadSafe*>(fi->fh);
  return 0;
}

int fat_readdir(const char* path,
                void* buf,
                fuse_fill_dir_t filler,
                off_t offset,
                struct fuse_file_info* fi) {
  VLOG(1) << "fat_readdir: " << path;
  filler(buf, ".", nullptr, 0);
  filler(buf, "..", nullptr, 0);
  int64_t start_sector = 0;
  if (strcmp(path, "/") == 0) {
    start_sector = g_volume->root_dir_start_sector();
  } else {
    DirectoryEntry entry;
    if (!GetDirectoryEntry(base::UTF8ToUTF16(path), &entry)) {
      return -ENOENT;
    }
    if (!entry.is_directory) {
      return -ENOTDIR;
    }
    start_sector = g_volume->GetClusterStartSector(entry.start_cluster);
  }
  if (!g_volume->ReadDirectory(
          start_sector,
          base::BindRepeating(
              [](fuse_fill_dir_t filler, void* buf,
                 const base::StringPiece16& name, const DirectoryEntry& entry) {
                filler(buf, base::UTF16ToUTF8(name).c_str(), nullptr, 0);
                return true;
              },
              filler, buf))) {
    return -EIO;
  }
  return 0;
}

}  // namespace

int mount_obb_fuse_main(const std::string& file_system_name,
                        const std::string& obb_filename,
                        const std::string& mount_path,
                        const std::string& owner_uid,
                        const std::string& owner_gid) {
  base::File file(base::FilePath(obb_filename),
                  base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file.IsValid()) {
    LOG(ERROR) << "Failed to open: " << obb_filename;
    return 1;
  }

  fat::Volume volume;
  if (!volume.Initialize(std::move(file))) {
    LOG(ERROR) << "Failed to initialize volume: " << obb_filename;
    return 1;
  }
  g_volume = &volume;

  const std::string mount_options =
      std::string("allow_other,default_permissions,uid=") + owner_uid +
      ",gid=" + owner_gid;
  const char* fuse_argv[] = {
     file_system_name.c_str(), mount_path.c_str(),
     "-f", "-o", mount_options.c_str(),
  };
  struct fuse_operations fat_ops = {};
#define SET_FAT_OP(name) fat_ops.name = fat_##name
  SET_FAT_OP(getattr);
  SET_FAT_OP(open);
  SET_FAT_OP(read);
  SET_FAT_OP(release);
  SET_FAT_OP(readdir);
#undef SET_FAT_OP
  fuse_main(base::size(fuse_argv), const_cast<char**>(fuse_argv), &fat_ops,
            nullptr);
  return 0;
}
