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

#define _XOPEN_SOURCE

#include <errno.h>
#include <limits.h>
#include <string.h>

#include <memory>
#include <utility>

#include <fbl/algorithm.h>
#include <minfs/fsck.h>
#include <minfs/host.h>
#include <minfs/minfs.h>
#include <minfs/transaction_limits.h>

#include "minfs.h"

char kDot[2] = ".";
char kDotDot[3] = "..";

namespace {
template <class T>
uint32_t ToU32(T in) {
  if (in > std::numeric_limits<uint32_t>::max()) {
    fprintf(stderr, "out of range %" PRIuMAX "\n", static_cast<uintmax_t>(in));
    exit(-1);
  }
  return static_cast<uint32_t>(in);
}
}  // namespace

// Returns the string version of |mode|.
static const char* GetModeString(uint32_t mode) {
  switch (mode & S_IFMT) {
    case S_IFREG:
      return "-";
    case S_IFCHR:
      return "c";
    case S_IFBLK:
      return "b";
    case S_IFDIR:
      return "d";
    default:
      return "?";
  }
}

// Adds PATH_PREFIX to path if it isn't there
void GetHostPath(const char* path, char* out) {
  out[0] = 0;
  int remaining = PATH_MAX;

  if (strncmp(path, PATH_PREFIX, PREFIX_SIZE)) {
    strncat(out, PATH_PREFIX, remaining);
    remaining -= strlen(PATH_PREFIX);
  }

  strncat(out, path, remaining);
}

// Checks if the given |path| is a directory, and return the answer in |*result|.
zx_status_t IsDirectory(const char* path, bool* result) {
  struct stat s;
  bool host = host_path(path);

  if (host) {
    if (stat(path, &s) < 0) {
      return ZX_ERR_IO;
    }
  } else {
    if (!emu_is_mounted()) {
      fprintf(stderr, "Cannot check directory of unmounted minfs partition\n");
      return ZX_ERR_INTERNAL;
    }

    if (emu_stat(path, &s) < 0) {
      return ZX_ERR_IO;
    }
  }

  if (S_ISDIR(s.st_mode)) {
    *result = true;
  } else {
    *result = false;
  }
  return ZX_OK;
}

// Copies a file to minfs from the host, or vice versa.
zx_status_t CopyFile(const char* src_path, const char* dst_path) {
  FileWrapper src;
  FileWrapper dst;

  if (FileWrapper::Open(src_path, O_RDONLY, 0, &src) < 0) {
    fprintf(stderr, "error: cannot open file '%s'\n", src_path);
    return ZX_ERR_IO;
  }

  if (FileWrapper::Open(dst_path, O_WRONLY | O_CREAT | O_EXCL, 0644, &dst) < 0) {
    fprintf(stderr, "error: cannot open file '%s'\n", dst_path);
    return ZX_ERR_IO;
  }

  char buffer[256 * 1024];
  ssize_t r;
  for (;;) {
    if ((r = src.Read(buffer, sizeof(buffer))) < 0) {
      fprintf(stderr, "error: reading from '%s'\n", src_path);
      break;
    } else if (r == 0) {
      break;
    }
    void* ptr = buffer;
    ssize_t len = r;
    while (len > 0) {
      if ((r = dst.Write(ptr, len)) < 0) {
        fprintf(stderr, "error: writing to '%s'\n", dst_path);
        goto done;
      }
      ptr = (void*)((uintptr_t)ptr + r);
      len -= r;
    }
  }
done:
  return r == 0 ? ZX_OK : ZX_ERR_IO;
}

// Attempts to make the directory at |path|.
// Returns a positive result if creation was successful or the specified directory already exists.
zx_status_t MakeDirectory(const char* path) {
  if (DirWrapper::Make(path, 0777) && errno != EEXIST) {
    fprintf(stderr, "minfs: could not create directory %s: %s\n", path, strerror(errno));
    return ZX_ERR_IO;
  }

  return ZX_OK;
}

zx_status_t MinfsCreator::Usage() {
  zx_status_t status = FsCreator::Usage();

  // Additional information about manifest format.
  fprintf(stderr, "\nThe format of the manifest must be as follows:\n");
  fprintf(stderr, "\t'dst/path=src/path'\n");
  fprintf(stderr, "with one dst/src pair on each line.\n");

  fprintf(stderr,
          "\nPrefix all minfs paths with '::' "
          "(unless they are included in a manifest).\n");
  return status;
}

bool MinfsCreator::IsCommandValid(Command command) {
  switch (command) {
    case Command::kMkfs:
    case Command::kFsck:
    case Command::kUsedDataSize:
    case Command::kUsedInodes:
    case Command::kUsedSize:
    case Command::kLs:
    case Command::kCp:
    case Command::kManifest:
    case Command::kMkdir:
    case Command::kAdd:
      return true;
    default:
      return false;
  }
}

bool MinfsCreator::IsOptionValid(Option option) {
  switch (option) {
    case Option::kDepfile:
    case Option::kReadonly:
    case Option::kOffset:
    case Option::kLength:
    case Option::kHelp:
      return true;
    default:
      return false;
  }
}

bool MinfsCreator::IsArgumentValid(Argument argument) {
  switch (argument) {
    case Argument::kManifest:
      return true;
    default:
      return false;
  }
}

zx_status_t MinfsCreator::ProcessManifestLine(FILE* manifest, const char* dir_path) {
  char src[PATH_MAX];
  src[0] = '\0';
  char dst[PATH_MAX];
  dst[0] = '\0';

  zx_status_t status;
  if ((status = ParseManifestLine(manifest, dir_path, &src[0], &dst[0])) != ZX_OK) {
    return status;
  }

  if (!strlen(src) || !strlen(dst)) {
    fprintf(stderr, "Manifest line must specify source and destination files\n");
    return ZX_ERR_INVALID_ARGS;
  }

  bool dir;
  if ((status = IsDirectory(src, &dir)) != ZX_OK) {
    return status;
  }

  if (dir) {
    fprintf(stderr, "Manifest cannot specify directory as source\n");
    return ZX_ERR_INVALID_ARGS;
  }

  // Make dst into minfs path.
  char emu_dst[PATH_MAX];
  GetHostPath(dst, emu_dst);

  // Process parent directories.
  if ((status = ProcessParentDirectories(emu_dst)) != ZX_OK) {
    return status;
  }

  // Copy src to dst.
  return ProcessFile(src, emu_dst);
}

zx_status_t MinfsCreator::ProcessCustom(int argc, char** argv, uint8_t* processed) {
  uint8_t required_args = 0;

  switch (GetCommand()) {
    case Command::kLs:
      __FALLTHROUGH;
    case Command::kMkdir: {
      required_args = 1;
      if (argc != required_args) {
        return ZX_ERR_INVALID_ARGS;
      }

      // A non-host path is required here since the ls and mkdir commands must be run on minfs.
      if (host_path(argv[0])) {
        fprintf(stderr, "Must specify path with prefix '::'");
        return ZX_ERR_INVALID_ARGS;
      }

      // ls and mkdir can only be run on one path at a time.
      if (!dir_list_.is_empty()) {
        fprintf(stderr, "Too many paths specified\n");
        return ZX_ERR_INVALID_ARGS;
      }

      if (GetCommand() == Command::kLs) {
        dir_list_.push_back(argv[0]);
        return ZX_OK;
      }

      zx_status_t status;
      if ((status = ProcessParentDirectories(argv[0])) != ZX_OK) {
        return status;
      }

      if ((status = ProcessDirectory(argv[0])) != ZX_OK) {
        return status;
      }
      break;
    }
    case Command::kCp: {
      required_args = 2;
      if (argc != required_args) {
        return ZX_ERR_INVALID_ARGS;
      }

      // If our source file is located within minfs, we need to mount the minfs image so that we
      // can process any child files/directories.
      zx_status_t status;
      if (!host_path(argv[0]) && (status = MountMinfs()) != ZX_OK) {
        return status;
      }

      char src[PATH_MAX];
      char dst[PATH_MAX];
      strncpy(src, argv[0], PATH_MAX);
      strncpy(dst, argv[1], PATH_MAX);

      if ((status = ProcessParentDirectories(dst)) != ZX_OK) {
        return status;
      }

      if ((status = ProcessEntityAndChildren(src, dst)) != ZX_OK) {
        return status;
      }
      break;
    }
    case Command::kManifest: {
      required_args = 1;
      if (argc != required_args) {
        return ZX_ERR_INVALID_ARGS;
      }
      zx_status_t status;
      if ((status = ProcessManifest(argv[0])) != ZX_OK) {
        return status;
      }
      break;
    }
    default:
      fprintf(stderr, "Arguments not supported\n");
      return ZX_ERR_INVALID_ARGS;
  }

  *processed = required_args;
  return ZX_OK;
}

zx_status_t MinfsCreator::CalculateRequiredSize(off_t* out) {
  uint32_t dir_count = static_cast<uint32_t>(dir_list_.size() + 1);  // dir_list_ + root

  // This is a rough estimate of how many directory data blocks will be needed.
  // This is not super robust and will not hold up if directories start requiring indirect blocks,
  // but for our current purposes it should be sufficient.
  uint32_t dir_blocks = ToU32(dir_count + (dir_bytes_ / minfs::kMinfsBlockSize));

  minfs::Superblock info;
  info.flags = 0;
  info.inode_count = minfs::kMinfsDefaultInodeCount;
  info.block_count = ToU32(data_blocks_ + dir_blocks);

  // Calculate number of blocks we will need for all minfs structures.
  uint32_t inode_bitmap_blocks =
      (info.inode_count + minfs::kMinfsBlockBits - 1) / minfs::kMinfsBlockBits;
  uint32_t block_bitmap_blocks =
      (info.block_count + minfs::kMinfsBlockBits - 1) / minfs::kMinfsBlockBits;
  uint32_t inode_table_blocks =
      (info.inode_count + minfs::kMinfsInodesPerBlock - 1) / minfs::kMinfsInodesPerBlock;

  info.ibm_block = 8;
  info.abm_block = info.ibm_block + fbl::round_up(inode_bitmap_blocks, 8u);
  info.ino_block = info.abm_block + fbl::round_up(block_bitmap_blocks, 8u);
  info.integrity_start_block = info.ino_block + inode_table_blocks;
  minfs::TransactionLimits limits(info);
  info.dat_block = info.integrity_start_block + limits.GetRecommendedIntegrityBlocks();

  *out = (info.dat_block + info.block_count) * minfs::kMinfsBlockSize;
  return ZX_OK;
}

zx_status_t MinfsCreator::Mkfs() {
  zx_status_t status;
  std::unique_ptr<minfs::Bcache> bc;

  // Create the bcache.
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }

  // Consume the bcache to mkfs.
  if ((status = minfs::Mkfs(bc.get())) != ZX_OK) {
    return status;
  }

  // Add any directories/files that have been pre-processed.
  if ((status = Add()) != ZX_OK) {
    fprintf(stderr,
            "Warning: Adding files on create failed - required size may have been "
            "miscalculated\n");
  }

  return status;
}

zx_status_t MinfsCreator::Fsck() {
  zx_status_t status;
  std::unique_ptr<minfs::Bcache> bc;
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }
  return minfs::Fsck(std::move(bc), minfs::FsckOptions{ .repair = true });
}

zx_status_t MinfsCreator::UsedDataSize() {
  zx_status_t status;
  uint64_t size;
  std::unique_ptr<minfs::Bcache> bc;
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }
  if ((status = minfs::UsedDataSize(bc, &size)) != ZX_OK) {
    return status;
  }

  printf("%" PRIu64 "\n", size);
  return ZX_OK;
}

zx_status_t MinfsCreator::UsedInodes() {
  zx_status_t status;
  uint64_t used_inodes;
  std::unique_ptr<minfs::Bcache> bc;
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }
  if ((status = minfs::UsedInodes(bc, &used_inodes)) != ZX_OK) {
    return status;
  }

  printf("%" PRIu64 "\n", used_inodes);
  return ZX_OK;
}

zx_status_t MinfsCreator::UsedSize() {
  zx_status_t status;
  uint64_t size;
  std::unique_ptr<minfs::Bcache> bc;
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }
  if ((status = minfs::UsedSize(bc, &size)) != ZX_OK) {
    return status;
  }

  printf("%" PRIu64 "\n", size);
  return ZX_OK;
}

zx_status_t MinfsCreator::Add() {
  zx_status_t status;
  // Mount the minfs.
  if ((status = MountMinfs()) != ZX_OK) {
    return status;
  }

  // Make all directories.
  for (size_t n = 0; n < dir_list_.size(); n++) {
    if ((status = MakeDirectory(dir_list_[n].c_str())) != ZX_OK) {
      return status;
    }
  }

  // Copy all files.
  for (size_t n = 0; n < file_list_.size(); n++) {
    if ((status = AppendDepfile(file_list_[n].first.c_str())) != ZX_OK) {
      return status;
    }
    if ((status = CopyFile(file_list_[n].first.c_str(), file_list_[n].second.c_str())) != ZX_OK) {
      return status;
    }
  }

  return ZX_OK;
}

zx_status_t MinfsCreator::Ls() {
  if (!file_list_.is_empty() || dir_list_.size() != 1) {
    fprintf(stderr, "ls requires one argument\n");
    return Usage();
  }

  zx_status_t status;
  if ((status = MountMinfs()) != ZX_OK) {
    return status;
  }

  const char* path = dir_list_[0].c_str();
  if (strncmp(path, PATH_PREFIX, PREFIX_SIZE)) {
    fprintf(stderr, "error: ls can only operate minfs paths (must start with %s)\n", PATH_PREFIX);
    return ZX_ERR_INVALID_ARGS;
  }

  DIR* d = emu_opendir(path);
  if (!d) {
    return ZX_ERR_IO;
  }

  struct dirent* dir_entry;
  char tmp[2048];
  struct stat stats;
  while ((dir_entry = emu_readdir(d)) != nullptr) {
    if (strcmp(dir_entry->d_name, ".") && strcmp(dir_entry->d_name, "..")) {
      memset(&stats, 0, sizeof(struct stat));
      if ((strlen(dir_entry->d_name) + strlen(path) + 2) <= sizeof(tmp)) {
        snprintf(tmp, sizeof(tmp), "%s/%s", path, dir_entry->d_name);
        emu_stat(tmp, &stats);
      }
      fprintf(stdout, "%s %8jd %s\n", GetModeString(stats.st_mode),
              static_cast<intmax_t>(stats.st_size), dir_entry->d_name);
    }
  }
  emu_closedir(d);
  return ZX_OK;
}

zx_status_t MinfsCreator::ProcessEntityAndChildren(char* src, char* dst) {
  bool dir;
  zx_status_t status;
  if ((status = IsDirectory(src, &dir)) != ZX_OK) {
    return status;
  }

  if (dir) {
    ProcessDirectory(dst);
  } else {
    return ProcessFile(src, dst);
  }

  DirWrapper current_dir;
  if (DirWrapper::Open(src, &current_dir)) {
    return ZX_ERR_IO;
  }

  size_t src_len = strlen(src);
  size_t dst_len = strlen(dst);
  struct dirent* dir_entry;
  while ((dir_entry = current_dir.ReadDir()) != nullptr) {
    if (!strcmp(dir_entry->d_name, ".") || !strcmp(dir_entry->d_name, "..")) {
      continue;
    }
    size_t name_len = strlen(dir_entry->d_name);
    if (src_len + name_len + 1 > PATH_MAX - 1 || dst_len + name_len + 1 > PATH_MAX - 1) {
      fprintf(stderr, "Path size exceeds PATH_MAX\n");
      return ZX_ERR_INVALID_ARGS;
    }
    strncat(src, "/", 1);
    strncat(src, dir_entry->d_name, PATH_MAX - src_len - 2);
    strncat(dst, "/", 1);
    strncat(dst, dir_entry->d_name, PATH_MAX - dst_len - 2);

    zx_status_t status = ProcessEntityAndChildren(src, dst);
    if (status != ZX_OK) {
      return status;
    }

    src[src_len] = '\0';
    dst[dst_len] = '\0';
  }
  return 0;
}

zx_status_t MinfsCreator::ProcessParentDirectories(char* path) {
  // Create parent directories if they don't exist.
  char* slash = strchr(path, '/');
  while (slash != nullptr) {
    *slash = '\0';

    char emu_path[PATH_MAX];
    GetHostPath(path, emu_path);

    zx_status_t status;
    if ((status = ProcessDirectory(emu_path)) != ZX_OK) {
      return status;
    }

    *slash = '/';
    slash = strchr(slash + 1, '/');
  }

  return ZX_OK;
}

zx_status_t MinfsCreator::ProcessDirectory(char* path) {
  if (!strncmp(path, PATH_PREFIX, strlen(path))) {
    // If |path| is the minfs root directory ("::"), return without processing.
    return ZX_OK;
  }

  // Check to see if |path| has already been processed.
  bool found = false;
  for (size_t i = 0; i < dir_list_.size(); i++) {
    if (!strcmp(path, dir_list_[i].c_str())) {
      found = true;
      break;
    }
  }

  if (!found) {
    // Only process the directory if it has not already been processed.
    if (GetCommand() == Command::kMkfs && !host_path(path)) {
      // Only calculate required space if we are running mkfs, and this is a minfs path.
      ProcessDirectoryEntry(path);
      ProcessDirectoryEntry(kDot);
      ProcessDirectoryEntry(kDotDot);
    }

    dir_list_.push_back(path);
  }

  return ZX_OK;
}

zx_status_t MinfsCreator::ProcessFile(char* src, char* dst) {
  struct stat stats;
  int result = host_path(src) ? stat(src, &stats) : emu_stat(src, &stats);
  if (result < 0) {
    fprintf(stderr, "Failed to stat file %s\n", src);
    return ZX_ERR_IO;
  }

  // Check if the file already exists in file_list_.
  for (size_t n = 0; n < file_list_.size(); n++) {
    if (!strcmp(dst, file_list_[n].second.c_str())) {
      if (!strcmp(src, file_list_[n].first.c_str())) {
        return ZX_OK;
      }

      // If the file does exist but the source does not match, return an error.
      fprintf(stderr, "Error: Source %s does not match existing source %s for destination %s\n",
              src, file_list_[n].first.c_str(), dst);
      return ZX_ERR_INVALID_ARGS;
    }
  }

  if (GetCommand() == Command::kMkfs && !host_path(dst)) {
    // Only calculate required size if we are copying to minfs, and we are mkfsing.
    zx_status_t status;
    if ((status = ProcessBlocks(stats.st_size)) != ZX_OK) {
      return status;
    }

    ProcessDirectoryEntry(dst);
  }

  file_list_.push_back(std::make_pair(src, dst));
  return ZX_OK;
}

void MinfsCreator::ProcessDirectoryEntry(char* path) {
  if (path == nullptr) {
    return;
  }
  char* last_slash = strrchr(path, '/');
  last_slash = last_slash == nullptr ? path : last_slash + 1;
  size_t component_length = strlen(last_slash);
  if (component_length > std::numeric_limits<uint8_t>::max()) {
    fprintf(stderr, "component too long");
    exit(-1);
  }
  dir_bytes_ += minfs::DirentSize(static_cast<uint8_t>(component_length));
}

zx_status_t MinfsCreator::ProcessBlocks(off_t file_size) {
  uint64_t total_blocks = 0;
  uint32_t remaining = ToU32((file_size + minfs::kMinfsBlockSize - 1) / minfs::kMinfsBlockSize);

  // Add direct blocks to the total.
  uint32_t direct_blocks = fbl::min(remaining, minfs::kMinfsDirect);
  total_blocks += direct_blocks;
  remaining -= direct_blocks;

  if (remaining) {
    // If more blocks remain, calculate how many indirect blocks we need.
    uint32_t indirect_blocks =
        fbl::min((remaining + minfs::kMinfsDirectPerIndirect + 1) / minfs::kMinfsDirectPerIndirect,
                 minfs::kMinfsIndirect);

    direct_blocks = fbl::min(remaining, indirect_blocks * minfs::kMinfsDirectPerIndirect);

    // Add blocks to the total, and update remaining.
    total_blocks += indirect_blocks + direct_blocks;
    remaining -= direct_blocks;

    if (remaining) {
      // If blocks remain past the indirect block range, calculate required doubly indirect
      // and indirect blocks.
      uint32_t dindirect_blocks = fbl::min(
          (remaining + minfs::kMinfsDirectPerDindirect + 1) / minfs::kMinfsDirectPerDindirect,
          minfs::kMinfsDoublyIndirect);

      indirect_blocks = fbl::min(
          (remaining + minfs::kMinfsDirectPerIndirect + 1) / minfs::kMinfsDirectPerIndirect,
          minfs::kMinfsDirectPerIndirect * minfs::kMinfsDoublyIndirect);

      direct_blocks =
          fbl::min(remaining, minfs::kMinfsDoublyIndirect * minfs::kMinfsDirectPerDindirect);

      // Add blocks to the total, and update remaining.
      total_blocks += dindirect_blocks + indirect_blocks + direct_blocks;
      remaining -= direct_blocks;

      if (remaining) {
        // If we still have more blocks remaining at this point, the file is larger than
        // the current minfs max file size.
        fprintf(stderr, "Error: File too large for minfs @ %" PRIu64 " bytes\n", file_size);
        return ZX_ERR_INVALID_ARGS;
      }
    }
  }

  // Add calculated blocks to the total so far.
  data_blocks_ += total_blocks;
  return ZX_OK;
}

zx_status_t MinfsCreator::GenerateBcache(std::unique_ptr<minfs::Bcache>* out) {
  uint32_t block_count = static_cast<uint32_t>(GetLength() / minfs::kMinfsBlockSize);

  // Duplicate the fd so that we can re-open the minfs partition if we need to.
  int dupfd = dup(fd_.get());

  std::unique_ptr<minfs::Bcache> bc;
  if (minfs::Bcache::Create(std::move(fd_), block_count, &bc) != ZX_OK) {
    fprintf(stderr, "error: cannot create block cache\n");
    return ZX_ERR_IO;
  }

  bc->SetOffset(GetOffset());
  fd_.reset(dupfd);
  *out = std::move(bc);
  return ZX_OK;
}

zx_status_t MinfsCreator::MountMinfs() {
  if (emu_is_mounted()) {
    // If we have already mounted minfs, do nothing.
    return ZX_OK;
  }

  zx_status_t status;
  std::unique_ptr<minfs::Bcache> bc;
  if ((status = GenerateBcache(&bc)) != ZX_OK) {
    return status;
  }

  return emu_mount_bcache(std::move(bc));
}

int main(int argc, char** argv) {
  MinfsCreator minfs;

  if (minfs.ProcessAndRun(argc, argv) != ZX_OK) {
    return -1;
  }

  return 0;
}
