#!/usr/bin/env bash
# disk-usage.sh - ranks the folders eating a disk, biggest first.
# READ-ONLY: walks and prints, changes nothing.
# Run: bash disk-usage.sh [path] [top]

set -u

PATH_TO_SCAN="${1:-$HOME}"
TOP="${2:-15}"

if [ ! -d "$PATH_TO_SCAN" ]; then
  echo "Path not found: $PATH_TO_SCAN" >&2
  exit 1
fi

echo "Scanning: $PATH_TO_SCAN"
echo "(read-only: this takes a moment on large folders)"
echo ""

# du -sk: kilobytes, summary per top-level entry; skip unreadable.
entries=$(du -sk "$PATH_TO_SCAN"/* "$PATH_TO_SCAN"/.[!.]* 2>/dev/null | sort -rn)
if [ -z "$entries" ]; then
  echo "Nothing found to measure."
  exit 0
fi

total=$(echo "$entries" | awk '{s+=$1} END {print s+0}')
shown=$(echo "$entries" | head -n "$TOP")
count=$(echo "$entries" | wc -l | tr -d ' ')

echo "$shown" | while IFS= read -r line; do
  kb=$(echo "$line" | awk '{print $1}')
  name=$(echo "$line" | cut -f2- | sed "s|^$PATH_TO_SCAN/||; s|^$PATH_TO_SCAN\\\\||")
  pct=$(awk -v k="$kb" -v t="$total" 'BEGIN {if (t>0) printf "%.1f", k*100/t; else print "0.0"}')
  bars=$(awk -v p="$pct" 'BEGIN {n=int(p/3); if (n<1) n=1; printf "%*s", n, ""}' | tr ' ' '#')
  size=$(awk -v k="$kb" 'BEGIN {if (k>=1048576) printf "%8.2f GB", k/1048576; else if (k>=1024) printf "%8.1f MB", k/1024; else printf "%8d KB", k}')
  short=$(basename "$name")
  printf '%-28s %s %6s%%  %s/\n' "$short" "$size" "$pct" "$bars"
done

if [ "$count" -gt "$TOP" ]; then
  rest=$(echo "$entries" | tail -n +"$((TOP+1))" | awk '{s+=$1} END {print s+0}')
  restsize=$(awk -v k="$rest" 'BEGIN {if (k>=1048576) printf "%8.2f GB", k/1048576; else if (k>=1024) printf "%8.1f MB", k/1024; else printf "%8d KB", k}')
  printf '%-28s %s  in %d more entries\n' "..." "$restsize" "$((count - TOP))"
fi

echo ""
totalsize=$(awk -v k="$total" 'BEGIN {if (k>=1048576) printf "%.2f GB", k/1048576; else printf "%.1f MB", k/1024}')
echo "Total measured: $totalsize in $count entries"