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

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/compiler.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <fs-management/mount.h>
#include <safemath/checked_math.h>

namespace {

struct {
  const char* name;
  disk_format_t df;
} FILESYSTEMS[] = {
    {"blobfs", DISK_FORMAT_BLOBFS},
    {"minfs", DISK_FORMAT_MINFS},
    {"fat", DISK_FORMAT_FAT},
};

int usage(void) {
  fprintf(stderr, "usage: mkfs [ <option>* ] devicepath filesystem\n");
  fprintf(stderr, " -h|--help                     Print this message\n");
  fprintf(stderr, " -v|--verbose                  Verbose mode\n");
  fprintf(stderr,
          " -s|--fvm_data_slices SLICES   If block device is on top of a FVM,\n"
          "                               the filesystem will have at least SLICES slices\n"
          "                               allocated for data.\n");
  fprintf(stderr, " values for 'filesystem' include:\n");
  for (size_t i = 0; i < countof(FILESYSTEMS); i++) {
    fprintf(stderr, "  '%s'\n", FILESYSTEMS[i].name);
  }
  return -1;
}

int parse_args(int argc, char** argv, mkfs_options_t* options, disk_format_t* df,
               char** devicepath) {
  static const struct option cmds[] = {
      {"help", no_argument, NULL, 'h'},
      {"verbose", no_argument, NULL, 'v'},
      {"fvm_data_slices", required_argument, NULL, 's'},
      {0, 0, 0, 0},
  };

  int opt_index = -1;
  int c = -1;

  while ((c = getopt_long(argc, argv, "hvs:", cmds, &opt_index)) >= 0) {
    switch (c) {
      case 'v':
        options->verbose = true;
        break;
      case 's':
        options->fvm_data_slices = safemath::checked_cast<uint32_t>(strtoul(optarg, NULL, 0));
        if (options->fvm_data_slices == 0) {
          fprintf(stderr, "Invalid Args: %s\n", strerror(errno));
          return usage();
        }
        break;
      case 'h':
        return usage();
      default:
        break;
    };
  };

  if (argc - optind < 1) {
    fprintf(stderr, "Invalid Args: Missing devicepath.\n");
    return usage();
  }

  if (argc - optind < 2) {
    fprintf(stderr, "Invalid Args: Missing filesystem.\n");
    return usage();
  }

  for (size_t i = 0; i < countof(FILESYSTEMS); i++) {
    if (!strcmp(FILESYSTEMS[i].name, argv[argc - 1])) {
      *df = FILESYSTEMS[i].df;
      break;
    }
  }

  if (*df == DISK_FORMAT_UNKNOWN) {
    fprintf(stderr, "fs_mkfs: Cannot format a device with filesystem '%s'\n", argv[2]);
    return usage();
  }

  size_t device_arg = argc - 2;
  *devicepath = argv[device_arg];

  return 0;
}

}  // namespace
int main(int argc, char** argv) {
  mkfs_options_t options = default_mkfs_options;
  char* devicepath;
  disk_format_t df;
  int r;
  if ((r = parse_args(argc, argv, &options, &df, &devicepath))) {
    return r;
  }

  if (options.verbose) {
    printf("fs_mkfs: Formatting device [%s]\n", devicepath);
  }

  if ((r = mkfs(devicepath, df, launch_stdio_sync, &options)) < 0) {
    fprintf(stderr, "fs_mkfs: Failed to format device: %d\n", r);
  }
  return r;
}
