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

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <stdalign.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/device/vfs.h>

#include <string>
#include <utility>

#include <fbl/unique_fd.h>

namespace fio = llcpp::fuchsia::io;

int usage(void) {
  fprintf(stderr, "usage: df [ <option>* ] [paths]\n");
  fprintf(stderr, "df displays the mounted filesystems for a list of paths\n");
  fprintf(stderr, " -i : List inode information instead of block usage\n");
  fprintf(stderr, " -h : Show sizes in human readable format (e.g., 1K 2M 3G)\n");
  fprintf(stderr, " --help : Show this help message\n");
  return -1;
}

typedef struct {
  bool node_usage;
  bool human_readable;
} df_options_t;

const char* root = "/";

int parse_args(int argc, const char** argv, df_options_t* options, const char*** dirs,
               size_t* count) {
  while (argc > 1) {
    if (!strcmp(argv[1], "-i")) {
      options->node_usage = true;
    } else if (!strcmp(argv[1], "-h")) {
      options->human_readable = true;
    } else if (!strcmp(argv[1], "--help")) {
      return usage();
    } else {
      break;
    }
    argc--;
    argv++;
  }
  if (argc >= 2) {
    *dirs = &argv[1];
    *count = argc - 1;
  } else {
    *dirs = &root;
    *count = 1;
  }
  return 0;
}

// Format for the header
const char* hfmt = "%-10s %10s %10s %10s %3s%%  %-10s  %-10s\n";
// Format for the human-readable header
const char* hrfmt = "%-10s %5s %5s %5s %5s%%  %-10s  %-10s\n";
// Format for the individual filesystems queried
const char* ffmt = "%-10s %10zu %10zu %10zu %3zu%%  %-10s  %-10s\n";

#define KB (1lu << 10)
#define MB (1lu << 20)
#define GB (1lu << 30)
#define TB (1lu << 40)
#define PB (1lu << 50)
#define EB (1lu << 60)

// Conditionally print the size if it falls within the range of the magnitude.
// [1.0XX, 999XX]
bool print_magnitude(int padding, size_t size, size_t magnitude, const char* mag_string) {
  if (size < 10 * magnitude) {
    printf("%*zu.%zu%s ", padding - 4, size / magnitude, size / (magnitude / 10) % 10, mag_string);
    return true;
  } else if (size < magnitude << 10) {
    printf("%*zu%s ", padding - 2, size / magnitude, mag_string);
    return true;
  }
  return false;
}

void print_human_readable(int padding, size_t size) {
  if (size < KB) {
    printf("%*s ", padding, "0");
  } else if (print_magnitude(padding, size, KB, "KB")) {
  } else if (print_magnitude(padding, size, MB, "MB")) {
  } else if (print_magnitude(padding, size, GB, "GB")) {
  } else if (print_magnitude(padding, size, TB, "TB")) {
  } else if (print_magnitude(padding, size, PB, "PB")) {
  } else {
    printf("%*zu ", padding, size);
  }
}

void print_fs_type(const char* name, const df_options_t* options, const fio::FilesystemInfo* info,
                   const char* device_path) {
  if (options->node_usage) {
    size_t nodes_total = info ? info->total_nodes : 0;
    size_t nodes_used = info ? info->used_nodes : 0;
    size_t nodes_available = nodes_total - nodes_used;
    size_t use_percentage = nodes_total ? nodes_used * 100 / nodes_total : 0;
    printf(ffmt, info != nullptr ? reinterpret_cast<const char*>(info->name.data()) : "?",
           nodes_total, nodes_used, nodes_available, use_percentage, name, device_path);
  } else {
    // Block Usage
    if (options->human_readable) {
      size_t bytes_total = info ? info->total_bytes : 0;
      size_t bytes_used = info ? info->used_bytes : 0;
      size_t bytes_available = bytes_total - bytes_used;
      size_t use_percentage = bytes_total ? bytes_used * 100 / bytes_total : 0;
      printf("%-10s ", info != nullptr ? reinterpret_cast<const char*>(info->name.data()) : "?");
      print_human_readable(5, bytes_total);
      print_human_readable(5, bytes_used);
      print_human_readable(5, bytes_available);
      printf("%5zu%%  ", use_percentage);
      printf("%-10s  ", name);
      printf("%-10s\n", device_path);
    } else {
      size_t blocks_total = info ? info->total_bytes >> 10 : 0;
      size_t blocks_used = info ? info->used_bytes >> 10 : 0;
      size_t blocks_available = blocks_total - blocks_used;
      size_t use_percentage = blocks_total ? blocks_used * 100 / blocks_total : 0;
      printf(ffmt, info != nullptr ? reinterpret_cast<const char*>(info->name.data()) : "?",
             blocks_total, blocks_used, blocks_available, use_percentage, name, device_path);
    }
  }
}

int main(int argc, const char** argv) {
  const char** dirs;
  size_t dircount;
  df_options_t options;
  memset(&options, 0, sizeof(df_options_t));
  int r;
  if ((r = parse_args(argc, argv, &options, &dirs, &dircount))) {
    return r;
  }

  if (options.node_usage) {
    printf(hfmt, "Filesystem", "Inodes", "IUsed", "IFree", "IUse", "Path", "Device");
  } else {
    if (options.human_readable) {
      printf(hrfmt, "Filesystem", "Size", "Used", "Avail", "Use", "Path", "Device");
    } else {
      printf(hfmt, "Filesystem", "1K-Blocks", "Used", "Available", "Use", "Path", "Device");
    }
  }

  // Try to open path with O_ADMIN so we can query for underlying block devices.
  // If we fail, open directory without O_ADMIN. Block devices will not be returned.
  for (size_t i = 0; i < dircount; i++) {
    fbl::unique_fd fd;
    bool admin = true;
    fd.reset(open(dirs[i], O_RDONLY | O_ADMIN));
    if (!fd) {
      fd.reset(open(dirs[i], O_RDONLY));
      if (!fd) {
        fprintf(stderr, "df: Could not open target: %s\n", dirs[i]);
        continue;
      }
      admin = false;
    }

    fio::FilesystemInfo info;
    fdio_cpp::FdioCaller caller(std::move(fd));
    auto result = fio::DirectoryAdmin::Call::QueryFilesystem(
        fidl::UnownedClientEnd<fio::DirectoryAdmin>(caller.borrow_channel()));
    if (!result.ok() || result->s != ZX_OK) {
      print_fs_type(dirs[i], &options, nullptr, "Unknown; cannot query filesystem");
      continue;
    }
    info = *result->info;
    info.name[fio::MAX_FS_NAME_BUFFER - 1] = '\0';

    auto result2 = fio::DirectoryAdmin::Call::GetDevicePath(
        fidl::UnownedClientEnd<fio::DirectoryAdmin>(caller.borrow_channel()));
    std::string path(std::string("I/O failure: ") + result2.status_string());
    if (result2.ok()) {
      if (result2->s == ZX_OK) {
        path = result2->path.get();
      } else if (!admin && result2->s == ZX_ERR_ACCESS_DENIED) {
        path = "Unknown; missing O_ADMIN";
      }
    }

    print_fs_type(dirs[i], &options, &info, path.c_str());
  }

  return 0;
}
