#!/bin/zsh

set -euo pipefail

declare -i FORCE=0

while (($# > 0)); do
	case "$1" in
	--force)
		FORCE=1
		shift
		;;
	*)
		if [[ -z "${WORKTREE_PATH:-}" ]]; then
			readonly WORKTREE_PATH="$1"
		fi
		shift
		;;
	esac
done

if [ -z "${WORKTREE_PATH:-}" ]; then
	echo "Usage: $0 [--force] <worktree-path>"
	exit 3
fi

readonly WORKTREE_DIR="$WORKTREE_PATH:t"

pushd "$WORKTREE_PATH" || exit 1

WORKTREE_ABSOLUTE_PATH=$(pwd)
readonly WORKTREE_ABSOLUTE_PATH

BRANCH_NAME=$(git branch --show-current)
readonly BRANCH_NAME

REMOTE_NAME=$(git config branch."${BRANCH_NAME}".pushremote || echo "")
if [ -z "${REMOTE_NAME}" ]; then
	REMOTE_NAME=$(git config branch."${BRANCH_NAME}".remote || echo "")
fi
readonly REMOTE_NAME

if [ -z "${REMOTE_NAME}" ]; then
	2>&1 echo "Failed to find push remote name for branch $BRANCH_NAME"
	popd || exit 1
	exit 3
fi

cd "$(git rev-parse --git-dir)"
cd ../../../

git pull

if [ $FORCE -ne 1 ]; then
	# TODO(laurynas): replace hardcoded "master" with the default branch check,
	# i.e. git remote show [remote-name] | grep 'HEAD branch'
	git branch --contains "$BRANCH_NAME" | grep -q master
	readonly BRANCH_MERGED=$?

	if [ $BRANCH_MERGED -ne 0 ]; then
		echo "Branch $BRANCH_NAME checked out at $WORKTREE_DIR is not fully merged"
		popd || exit 1
		exit 2
	fi
fi

rm -rf "$WORKTREE_ABSOLUTE_PATH"
popd -n

git worktree prune

if ! git push "$REMOTE_NAME" -d "$BRANCH_NAME"; then
	echo "Failed to delete the remote branch, perhaps it was already deleted"
fi

if [ $FORCE -ne 1 ]; then
	git branch -d "$BRANCH_NAME"
else
	git branch -D "$BRANCH_NAME"
fi

git fetch --all -p
