#!/bin/sh
# meowfetch - a tiny system info fetcher with a cat. POSIX sh, no dependencies.
# https://dl.catg1rl.com/  MIT License
VERSION=0.2.0

usage() {
	cat <<USAGE
meowfetch $VERSION - system info, with a cat

usage: meowfetch [-c CAT] [-n] [-l] [-v]
  -c CAT  pick a cat: loaf, sit, sleep, box (default: random)
  -n      no colours
  -l      list cats
  -v      print version
USAGE
}

cat_loaf() {
	printf '%s\n' \
	'   /\_/\    ' \
	'  ( o.o )   ' \
	'  (  _  )~  ' \
	'  /_/ \_\   ' \
	'            '
}
cat_sit() {
	printf '%s\n' \
	'    /\_/\   ' \
	'   ( ^.^ )  ' \
	'    > ^ <   ' \
	'   /     \  ' \
	'  (_|   |_) '
}
cat_sleep() {
	printf '%s\n' \
	'            ' \
	'    |\__/,| ' \
	'  _.|o o  |_' \
	' -(((---(((-' \
	'      zzz   '
}
cat_box() {
	printf '%s\n' \
	'   /\_/\    ' \
	'  ( -.- )   ' \
	' +-------+  ' \
	' |  box  |  ' \
	' +-------+  '
}

info_os() {
	if [ -r /etc/os-release ]; then
		. /etc/os-release
		printf '%s' "${PRETTY_NAME:-$NAME}"
	else
		uname -s
	fi
}
info_uptime() {
	if [ -r /proc/uptime ]; then
		s=$(cut -d. -f1 /proc/uptime)
	else
		s=$(( $(date +%s) - $(sysctl -n kern.boottime 2>/dev/null | sed 's/.*sec = \([0-9]*\).*/\1/') ))
	fi
	d=$((s / 86400)); h=$((s % 86400 / 3600)); m=$((s % 3600 / 60))
	if [ "$d" -gt 0 ]; then printf '%dd %dh %dm' "$d" "$h" "$m"; else printf '%dh %dm' "$h" "$m"; fi
}
info_cpu() {
	if [ -r /proc/cpuinfo ]; then
		sed -n 's/^model name[[:space:]]*: //p' /proc/cpuinfo | head -n1 | tr -s ' '
	else
		sysctl -n machdep.cpu.brand_string 2>/dev/null || uname -m
	fi
}
info_mem() {
	if [ -r /proc/meminfo ]; then
		awk '/^MemTotal/{t=$2} /^MemAvailable/{a=$2} END{printf "%d MiB / %d MiB", (t-a)/1024, t/1024}' /proc/meminfo
	fi
}
info_shell() { basename "${SHELL:-sh}"; }
info_pkgs() {
	n=""
	if command -v dpkg-query >/dev/null 2>&1; then n="$(dpkg-query -f '.\n' -W 2>/dev/null | wc -l | tr -d ' ') (dpkg)"
	elif command -v rpm >/dev/null 2>&1; then n="$(rpm -qa 2>/dev/null | wc -l | tr -d ' ') (rpm)"
	elif command -v pacman >/dev/null 2>&1; then n="$(pacman -Qq 2>/dev/null | wc -l | tr -d ' ') (pacman)"
	elif [ -d /var/db/pkg ]; then n="$(find /var/db/pkg -mindepth 2 -maxdepth 2 -type d | wc -l | tr -d ' ') (portage)"
	elif command -v apk >/dev/null 2>&1; then n="$(apk info 2>/dev/null | wc -l | tr -d ' ') (apk)"
	elif command -v brew >/dev/null 2>&1; then n="$(brew list -1 2>/dev/null | wc -l | tr -d ' ') (brew)"
	fi
	printf '%s' "${n:-unknown}"
}

color=1; pick=""
while getopts c:nlvh opt; do
	case $opt in
		c) pick=$OPTARG ;;
		n) color=0 ;;
		l) printf 'loaf\nsit\nsleep\nbox\n'; exit 0 ;;
		v) echo "meowfetch $VERSION"; exit 0 ;;
		*) usage; exit 0 ;;
	esac
done
[ -n "${NO_COLOR:-}" ] && color=0
[ -t 1 ] || color=0

if [ -z "$pick" ]; then
	set -- loaf sit sleep box
	i=$(( $(od -An -N1 -tu1 /dev/urandom 2>/dev/null || echo 0) % 4 + 1 ))
	eval "pick=\${$i}"
fi
case $pick in loaf|sit|sleep|box) ;; *) echo "meowfetch: no such cat: $pick" >&2; exit 1 ;; esac

if [ "$color" = 1 ]; then A=$(printf '\033[35m'); B=$(printf '\033[1m'); R=$(printf '\033[0m'); else A=; B=; R=; fi

user=${USER:-$(id -un)}; host=$(uname -n)
tmp=${TMPDIR:-/tmp}/meowfetch.$$
trap 'rm -f "$tmp"' EXIT INT TERM
{
	printf '%s%s@%s%s\n' "$B" "$user" "$host" "$R"
	printf '%sos%s      %s\n' "$A" "$R" "$(info_os)"
	printf '%skernel%s  %s\n' "$A" "$R" "$(uname -r)"
	printf '%suptime%s  %s\n' "$A" "$R" "$(info_uptime)"
	printf '%spkgs%s    %s\n' "$A" "$R" "$(info_pkgs)"
	printf '%sshell%s   %s\n' "$A" "$R" "$(info_shell)"
	printf '%scpu%s     %s\n' "$A" "$R" "$(info_cpu)"
	printf '%smemory%s  %s\n' "$A" "$R" "$(info_mem)"
} > "$tmp"
{ "cat_$pick"; printf '%12s\n' '' '' ''; } | while IFS= read -r art; do
	IFS= read -r line <&3 || line=""
	printf '%s%s%s  %s\n' "$A" "$art" "$R" "$line"
done 3< "$tmp"
