/* df.c - report free disk space.
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/df.html

USE_DF(NEWTOY(df, "HPkhit*a[-HPh]", TOYFLAG_SBIN))

config DF
  bool "df"
  default y
  help
    usage: df [-HPkhi] [-t type] [FILE...]

    The "disk free" command shows total/used/available disk space for
    each filesystem listed on the command line, or all currently mounted
    filesystems.

    -a	Show all (including /proc and friends)
    -P	The SUSv3 "Pedantic" option
    -k	Sets units back to 1024 bytes (the default without -P)
    -h	Human readable (K=1024)
    -H	Human readable (k=1000)
    -i	Show inodes instead of blocks
    -t type	Display only filesystems of this type

    Pedantic provides a slightly less useful output format dictated by POSIX,
    and sets the units to 512 bytes instead of the default 1024 bytes.
*/

#define FOR_df
#include "toys.h"

GLOBALS(
  struct arg_list *t;

  int units, width[6];
)

static void measure_columns(char *s[])
{
  int i;

  for (i = 0; i<5; i++) TT.width[i] = maxof(TT.width[i], strlen(s[i]));
}

static void print_columns(char **dsuapm)
{
  int i;

  for (i = 0; i<6; i++) printf(!i ? "%-*s" : " %*s", TT.width[i], dsuapm[i]);
  xputc('\n');
}

static void print_header()
{
  char *dsuapm[] = {"Filesystem", "Size", "Used", "Avail", "Use%","Mounted on"};

  // The filesystem column is always at least this wide.
  TT.width[0] = maxof(TT.width[0], 14+(FLAG(H)||FLAG(h)));

  if (FLAG(i)) memcpy(dsuapm+1, (char *[]){"Inodes", "IUsed", "IFree", "IUse%"},
                      sizeof(char *)*4);
  else {
    if (!(FLAG(H)||FLAG(h))) {
      dsuapm[1] = TT.units == 512 ? "512-blocks" :
        FLAG(P) ? "1024-blocks" : "1K-blocks";
      dsuapm[3] = "Available";
      if (FLAG(P)) dsuapm[4] = "Capacity";
    }
  }

  measure_columns(dsuapm);
  TT.width[5] = -1;
  print_columns(dsuapm);
}

static void show_mt(struct mtab_list *mt, int measuring)
{
  unsigned long long suap[4], block = 1, ll;
  char *dsuapm[6]; // device, size, used, avail, percent, mount
  int i;

  // If we don't have -a, skip overmounted and synthetic filesystems.
  if (!mt || (!FLAG(a) && (!mt->stat.st_dev || !mt->statvfs.f_blocks))) return;

  // If we have -t, skip other filesystem types
  if (TT.t) {
    struct arg_list *al;

    for (al = TT.t; al; al = al->next) if (!strcmp(mt->type, al->arg)) break;

    if (!al) return;
  }

  // Prepare filesystem display fields
  *dsuapm = *mt->device == '/' ? xabspath(mt->device, 0) : 0;
  if (!*dsuapm) *dsuapm = mt->device;
  if (!mt->stat.st_dev) for (i = 1; i<5; i++) dsuapm[i] = "-";
  else {
    if (FLAG(i)) {
      suap[0] = mt->statvfs.f_files;
      suap[1] = mt->statvfs.f_files - mt->statvfs.f_ffree;
      suap[2] = getuid() ? mt->statvfs.f_favail : mt->statvfs.f_ffree;
    } else {
      block = maxof(mt->statvfs.f_frsize, 1);
      suap[0] = mt->statvfs.f_blocks;
      suap[1] = mt->statvfs.f_blocks - mt->statvfs.f_bfree;
      suap[2] = getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree;
    }

    // Scale and convert to strings
    dsuapm[1] = toybuf;
    for (i = 0; i<3; i++) {
      suap[i] = (block*suap[i])/TT.units;

      if (FLAG(H)||FLAG(h))
        human_readable(dsuapm[i+1], suap[i], FLAG(H) ? HR_1000 : 0);
      else sprintf(dsuapm[i+1], "%llu", suap[i]);
      dsuapm[i+2] = strchr(dsuapm[i+1], 0)+1;
    }

    // percent
    if ((suap[3] = ll = suap[1]+suap[2])) {
      suap[3] = (block = suap[1]*100)/ll;
      if (block != suap[3]*ll) suap[3]++;
    }
    sprintf(dsuapm[4], "%llu%%", suap[3]);
  }
  dsuapm[5] = mt->dir;

  if (measuring) measure_columns(dsuapm);
  else print_columns(dsuapm);

  if (*dsuapm != mt->device) free(*dsuapm);
}

void df_main(void)
{
  struct mtab_list *mt, *mtstart, *mtend, *mt2, *mt3;
  int measuring;
  char **next;

  // Units are 512 bytes if you select "pedantic" without "kilobytes".
  if (FLAG(H)||FLAG(h)||FLAG(i)) TT.units = 1;
  else TT.units = FLAG(P) && !FLAG(k) ? 512 : 1024;

  if (!(mtstart = xgetmountlist(0))) return;
  mtend = dlist_terminate(mtstart);

  // If we have a list of filesystems on the command line, loop through them.
  if (*toys.optargs) {
    // Measure the names then output the table.
    for (measuring = 1;;) {
      for (next = toys.optargs; *next; next++) {
        struct stat st;

        // Stat it (complain if we can't).
        if (stat(*next, &st)) {
          if (!measuring) perror_msg("'%s'", *next);
        } else {
          // Find and display this filesystem.  Use _last_ hit in case of
          // overmounts (which is first hit in the reversed list).
          for (mt = mtend, mt2 = 0; mt; mt = mt->prev) {
            if (!mt2 && st.st_dev == mt->stat.st_dev) mt2 = mt;
            if (st.st_rdev && (st.st_rdev == mt->stat.st_dev)) break;
          }
          show_mt(mt ? : mt2, measuring);
        }
      }
      if (!measuring--) break;
      print_header();
    }
  } else {
    // Loop through mount list to filter out overmounts.
    for (mt = mtend; mt; mt = mt->prev) {
      for (mt3 = mt, mt2 = mt->prev; mt2; mt2 = mt2->prev) {
        if (mt->stat.st_dev == mt2->stat.st_dev) {
          // For --bind mounts, show earliest mount
          if (!strcmp(mt->device, mt2->device)) {
            mt3->stat.st_dev = 0;
            mt3 = mt2;
          } else mt2->stat.st_dev = 0;
        }
      }
    }

    // Measure the names then output the table (in filesystem creation order).
    for (measuring = 1;;) {
      for (mt = mtstart; mt; mt = mt->next) show_mt(mt, measuring);
      if (!measuring--) break;
      print_header();
    }
  }

  if (CFG_TOYBOX_FREE) llist_traverse(mtstart, free);
}
