/* du.c - disk usage program.
 *
 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/du.html
 *
 * TODO: cleanup

USE_DU(NEWTOY(du, "d#<0hmlcaHkKLsx[-HL][-kKmh]", TOYFLAG_USR|TOYFLAG_BIN))

config DU
  bool "du"
  default y
  help
    usage: du [-d N] [-askxHLlmc] [file...]

    Show disk usage, space consumed by files and directories.

    Size in:
    -k    1024 byte blocks (default)
    -K    512 byte blocks (posix)
    -m    megabytes
    -h    human readable format (e.g., 1K 243M 2G )

    What to show:
    -a    all files, not just directories
    -H    follow symlinks on cmdline
    -L    follow all symlinks
    -s    only total size of each argument
    -x    don't leave this filesystem
    -c    cumulative total
    -d N  only depth < N
    -l    disable hardlink filter
*/

#define FOR_du
#include "toys.h"

GLOBALS(
  long maxdepth;

  unsigned long depth, total;
  dev_t st_dev;
  void *inodes;
)

typedef struct node_size {
  struct dirtree *node;
  long size;
} node_size;

// Print the size and name, given size in bytes
static void print(long long size, struct dirtree *node)
{
  char *name = "total";

  if (TT.maxdepth && TT.depth > TT.maxdepth) return;

  if (toys.optflags & FLAG_h) {
    human_readable(toybuf, size, 0);
    printf("%s", toybuf);
  } else {
    int bits = 10;

    if (toys.optflags & FLAG_K) bits = 9;
    else if (toys.optflags & FLAG_m) bits = 20;

    printf("%llu", (size>>bits)+!!(size&((1<<bits)-1)));
  }
  if (node) name = dirtree_path(node, NULL);
  xprintf("\t%s\n", name);
  if (node) free(name);
}

// Return whether or not we've seen this inode+dev, adding it to the list if
// we haven't.
static int seen_inode(void **list, struct stat *st)
{
  if (!st) llist_traverse(st, free);

  // Skipping dir nodes isn't _quite_ right. They're not hardlinked, but could
  // be bind mounted. Still, it's more efficient and the archivers can't use
  // hardlinked directory info anyway. (Note that we don't catch bind mounted
  // _files_ because it doesn't change st_nlink.)
  else if (!S_ISDIR(st->st_mode) && st->st_nlink > 1) {
    struct inode_list {
      struct inode_list *next;
      ino_t ino;
      dev_t dev;
    } *new;

    for (new = *list; new; new = new->next)
      if(new->ino == st->st_ino && new->dev == st->st_dev)
        return 1;

    new = xzalloc(sizeof(*new));
    new->ino = st->st_ino;
    new->dev = st->st_dev;
    new->next = *list;
    *list = new;
  }

  return 0;
}

// dirtree callback, compute/display size of node
static int do_du(struct dirtree *node)
{
  unsigned long blocks;

  if (!node->parent) TT.st_dev = node->st.st_dev;
  else if (!dirtree_notdotdot(node)) return 0;

  // detect swiching filesystems
  if ((toys.optflags & FLAG_x) && (TT.st_dev != node->st.st_dev))
    return 0;

  // Don't loop endlessly on recursive directory symlink
  if (toys.optflags & FLAG_L) {
    struct dirtree *try = node;

    while ((try = try->parent))
      if (node->st.st_dev==try->st.st_dev && node->st.st_ino==try->st.st_ino)
        return 0;
  }

  // Don't count hard links twice
  if (!(toys.optflags & FLAG_l) && !node->again)
    if (seen_inode(&TT.inodes, &node->st)) return 0;

  // Collect child info before printing directory size
  if (S_ISDIR(node->st.st_mode)) {
    if (!node->again) {
      TT.depth++;
      return DIRTREE_COMEAGAIN|(DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L));
    } else TT.depth--;
  }

  // Modern compilers' optimizers are insane and think signed overflow
  // behaves differently than unsigned overflow. Sigh. Big hammer.
  blocks = node->st.st_blocks + (unsigned long)node->extra;
  node->extra = blocks;
  if (node->parent)
    node->parent->extra = (unsigned long)node->parent->extra+blocks;
  else TT.total += node->extra;

  if ((toys.optflags & FLAG_a) || !node->parent
      || (S_ISDIR(node->st.st_mode) && !(toys.optflags & FLAG_s)))
  {
    blocks = node->extra;
    print(blocks*512LL, node);
  }

  return 0;
}

void du_main(void)
{
  char *noargs[] = {".", 0}, **args;

  // Loop over command line arguments, recursing through children
  for (args = toys.optc ? toys.optargs : noargs; *args; args++)
    dirtree_handle_callback(dirtree_start(*args, toys.optflags&(FLAG_H|FLAG_L)),
      do_du);
  if (toys.optflags & FLAG_c) print(TT.total*512, 0);

  if (CFG_TOYBOX_FREE) seen_inode(TT.inodes, 0);
}
