#!/usr/bin/env bash

set -eo pipefail

repo_root="$(cd "$(dirname "$0")/.." && pwd -P)"
session="$PI_AGI_TMUX_SESSION"
[[ -n "$session" ]] || session="pi-agi-live-$UID"

die() {
	printf 'pi-agi live test: %s\n' "$*" >&2
	exit 1
}

usage() {
	cat <<'EOF'
Usage: npm run live -- <command> [argument]

Commands:
  start [workspace]   Start local Pi in a new owned tmux session.
  attach              Attach to the live TUI.
  enable              Type /agi and Enter into the TUI.
  send <text>         Send one prompt followed by Enter.
  capture [file]      Print full scrollback, or save it to file.
  status              Show the exact session, pane, process, and workspace.
  stop                Gracefully close only the owned live-test session.

Environment:
  PI_AGI_TMUX_SESSION  Override the tmux session name.
  PI_BIN               Override the pi executable.

The default workspace is a new /tmp/pi-agi-live.* directory. It is retained
after stop so state, sessions, and worker runs remain inspectable.
EOF
}

require_command() {
	command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
}

validate_session_name() {
	[[ "$session" =~ ^[A-Za-z0-9_.-]+$ ]] ||
		die "unsafe tmux session name: $session"
}

session_exists() {
	tmux has-session -t "$session" 2>/dev/null
}

owned_value() {
	tmux show-options -v -t "$session" "@pi_agi_live_$1" 2>/dev/null || true
}

verify_owned_session() {
	session_exists || die "tmux session does not exist: $session"
	local owner
	owner="$(owned_value repo)"
	if [[ "$owner" != "$repo_root" ]]; then
		[[ -n "$owner" ]] || owner="missing"
		die "refusing to operate on unowned session '$session' (marker: $owner)"
	fi
}

print_identity() {
	verify_owned_session
	local pane_pid pane_command pane_path workspace
	pane_pid="$(tmux display-message -p -t "$session:0.0" '#{pane_pid}')"
	pane_command="$(tmux display-message -p -t "$session:0.0" '#{pane_current_command}')"
	pane_path="$(tmux display-message -p -t "$session:0.0" '#{pane_current_path}')"
	workspace="$(owned_value workspace)"
	printf 'session:   %s\n' "$session"
	printf 'workspace: %s\n' "$workspace"
	printf 'pane pid:  %s\n' "$pane_pid"
	printf 'command:   %s\n' "$pane_command"
	printf 'cwd:       %s\n' "$pane_path"
	ps -o pid,ppid,user,stat,lstart,cmd -p "$pane_pid"
}

start_session() {
	require_command tmux
	validate_session_name
	session_exists && die "tmux session already exists: $session"

	local workspace=""
	[[ $# -eq 0 ]] || workspace="$1"
	if [[ -z "$workspace" ]]; then
		workspace="$(mktemp -d /tmp/pi-agi-live.XXXXXX)"
	else
		mkdir -p "$workspace"
		workspace="$(cd "$workspace" && pwd -P)"
	fi

	if [[ ! -d "$workspace/.git" ]]; then
		require_command git
		git -C "$workspace" init -q
	fi
	mkdir -p "$workspace/sessions"

	local pi_bin="$PI_BIN"
	if [[ -z "$pi_bin" ]]; then
		pi_bin="$(command -v pi || true)"
	fi
	[[ -n "$pi_bin" && -x "$pi_bin" ]] || die "pi executable not found; set PI_BIN"

	local entry="$repo_root/src/index.ts"
	[[ -f "$entry" ]] || die "extension entry not found: $entry"

	local launch
	printf -v launch 'exec %q -ne -e %q --approve --session-dir %q --name %q' \
		"$pi_bin" "$entry" "$workspace/sessions" "$session"

	tmux new-session -d -s "$session" -c "$workspace" "$launch"
	tmux set-option -t "$session" @pi_agi_live_repo "$repo_root"
	tmux set-option -t "$session" @pi_agi_live_workspace "$workspace"
	tmux set-option -w -t "$session" history-limit 100000

	printf 'Started local pi-agi TUI.\n'
	printf '  session:   %s\n' "$session"
	printf '  workspace: %s\n' "$workspace"
	printf '  source:    %s\n' "$entry"
	printf '\nAttach with: npm run live -- attach\n'
	printf 'Then type /agi, or run: npm run live -- enable\n'
}

attach_session() {
	require_command tmux
	validate_session_name
	verify_owned_session
	exec tmux attach-session -t "$session"
}

send_text() {
	require_command tmux
	validate_session_name
	verify_owned_session
	[[ $# -gt 0 ]] || die "send requires text"
	local payload="$*"
	tmux send-keys -t "$session:0.0" -l "$payload"
	tmux send-keys -t "$session:0.0" Enter
}

capture_session() {
	require_command tmux
	validate_session_name
	verify_owned_session
	local output=""
	[[ $# -eq 0 ]] || output="$1"
	if [[ -z "$output" ]]; then
		tmux capture-pane -p -S - -t "$session:0.0"
		return
	fi
	output="$(cd "$(dirname "$output")" && pwd -P)/$(basename "$output")"
	tmux capture-pane -p -S - -t "$session:0.0" >"$output"
	printf 'Saved full tmux scrollback to %s\n' "$output"
}

stop_session() {
	require_command tmux
	validate_session_name
	print_identity

	local attempt
	for attempt in 1 2; do
		tmux send-keys -t "$session:0.0" C-d
		for _ in {1..20}; do
			session_exists || {
				printf 'Session exited gracefully.\n'
				return
			}
			sleep 0.1
		done
	done

	verify_owned_session
	printf 'Graceful EOF did not close the owned tmux shell; removing exact session %s.\n' "$session"
	tmux kill-session -t "$session"
}

require_command tmux
validate_session_name

action="help"
[[ $# -eq 0 ]] || action="$1"
if [[ $# -gt 0 ]]; then
	shift
fi

case "$action" in
	start) start_session "$@" ;;
	attach) attach_session ;;
	enable) send_text "/agi" ;;
	send) send_text "$@" ;;
	capture) capture_session "$@" ;;
	status) print_identity ;;
	stop) stop_session ;;
	help | -h | --help) usage ;;
	*) usage; die "unknown command: $action" ;;
esac
