#!/bin/bash
# Remove debhelper-generated files from debian/ (logs, substvars, staging dirs, …).
#
# Usage:
#   debian-dh-clean [options] [path]
#
# path may be the source tree (containing debian/) or debian/ itself.
# Default: current directory.
#
# Install:
#   sudo install -m 755 debian-dh-clean /usr/local/bin/debian-dh-clean

set -euo pipefail

readonly PROG="${0##*/}"

usage() {
	cat <<EOF
Usage: ${PROG} [options] [path]

Remove debhelper build artifacts under debian/:
  .debhelper/  *.debhelper.log  *.substvars  *.debhelper
  debhelper-build-stamp  files  debian/<pkg>/ staging trees  debian/tmp/

path defaults to the current directory. It may point at the source root
or at debian/ directly.

Options:
  -n, --dry-run   Show what would be removed, do not delete
  -v, --verbose   Pass -v to dh_clean when available
  -h, --help      Show this help
EOF
}

die() {
	echo "${PROG}: error: $*" >&2
	exit 1
}

resolve_source_dir() {
	local arg="${1:-.}"

	if [ ! -e "$arg" ]; then
		die "path not found: $arg"
	fi

	if [ -d "$arg/debian" ]; then
		cd "$arg" && pwd
	elif [ "$(basename "$arg")" = "debian" ] && [ -d "$arg" ]; then
		cd "$(dirname "$arg")" && pwd
	else
		die "no debian/ directory under: $arg"
	fi
}

manual_clean() {
	local debian_dir="$1"
	local dry_run="$2"
	local rm_cmd rmdir_cmd

	if [ "$dry_run" = 1 ]; then
		rm_cmd='echo rm -rf'
		rmdir_cmd='echo rm -f'
	else
		rm_cmd='rm -rf'
		rmdir_cmd='rm -f'
	fi

	# Same patterns as dh_clean(1); no debian/clean or find(1) sweep here.
	[ -d "$debian_dir/.debhelper" ] && $rm_cmd -- "$debian_dir/.debhelper"
	[ -f "$debian_dir/debhelper-build-stamp" ] && $rmdir_cmd -- "$debian_dir/debhelper-build-stamp"
	[ -f "$debian_dir/files" ] && $rmdir_cmd -- "$debian_dir/files"

	shopt -s nullglob
	for f in "$debian_dir"/*.debhelper.log "$debian_dir"/*.substvars "$debian_dir"/*.*.debhelper; do
		[ -e "$f" ] || continue
		$rmdir_cmd -- "$f"
	done
	shopt -u nullglob

	if [ -f "$debian_dir/control" ]; then
		local pkg
		while read -r pkg; do
			[ -n "$pkg" ] || continue
			[ -d "$debian_dir/$pkg" ] && $rm_cmd -- "$debian_dir/$pkg"
		done < <(awk '/^Package:/ { print $2 }' "$debian_dir/control")
	fi

	[ -d "$debian_dir/tmp" ] && $rm_cmd -- "$debian_dir/tmp"
}

main() {
	local dry_run=0 verbose=0 path='.'
	local src_dir debian_dir dh_args=()

	while [ $# -gt 0 ]; do
		case "$1" in
		-n|--dry-run) dry_run=1 ;;
		-v|--verbose) verbose=1 ;;
		-h|--help) usage; exit 0 ;;
		-*) die "unknown option: $1 (try --help)" ;;
		*) path="$1" ;;
		esac
		shift
	done

	src_dir="$(resolve_source_dir "$path")"
	debian_dir="${src_dir}/debian"

	if [ "$dry_run" = 1 ]; then
		echo "==> Would clean debhelper artifacts in ${debian_dir}"
	else
		echo "==> Cleaning debhelper artifacts in ${debian_dir}"
	fi

	if command -v dh_clean >/dev/null 2>&1; then
		[ "$verbose" = 1 ] && dh_args+=(-v)
		if [ "$dry_run" = 1 ]; then
			( cd "$src_dir" && dh_clean "${dh_args[@]}" -v ) | sed 's/^\(rm\|find\)/would &/'
		else
			( cd "$src_dir" && dh_clean "${dh_args[@]}" )
		fi
	else
		echo "${PROG}: warning: dh_clean not found, using built-in fallback" >&2
		manual_clean "$debian_dir" "$dry_run"
	fi
}

main "$@"
