#!/usr/bin/env bash
# Oi: single-click Navigator trigger for acme.
# Spawns or reuses a persistent Navigator session scoped to cwd,
# sends current file context, and opens the chat window.
set -euo pipefail

cmd=${0##*/}
die() { printf '%s: %s\n' "$cmd" "$*" >&2; exit 1; }

OLLIE=${OLLIE:-$HOME/mnt/ollie}
try() { "$@" 2>/dev/null || { ollie-remount && "$@"; }; }

# Workspace detection: find workspace root (indicator file) or git/worktree root.
# Indicators: comma-delimited list of filenames that mark a workspace.
WORKSPACE_INDICATORS=".mdworkspace"

detect_workspace() {
	local dir="$1"
	local git_root=""

	while [ "$dir" != "/" ]; do
		# Check for workspace indicator
		local IFS=,
		for ind in $WORKSPACE_INDICATORS; do
			[ -e "$dir/$ind" ] && { printf '%s\n' "$dir"; return; }
		done
		unset IFS
		# Check for .git
		if [ -z "$git_root" ] && [ -e "$dir/.git" ]; then
			if [ -d "$dir/.git" ]; then
				# Real repo — this is a root
				git_root="$dir"
			elif ! grep -q '/modules/' "$dir/.git" 2>/dev/null; then
				# Worktree (.git file pointing to .git/worktrees/) — treat as root
				git_root="$dir"
			fi
			# Submodule (.git file pointing to .git/modules/) — skip
		fi
		dir=$(dirname "$dir")
	done

	[ -n "$git_root" ] && { printf '%s\n' "$git_root"; return; }
	return 1
}

cwd=$(detect_workspace "$(pwd)") || die "not in a git repo or workspace"
hash=$(printf '%s' "$cwd" | cksum | awk '{print $1}')
NAV_NAME="nav-${hash}"
NAV_PATH="$OLLIE/s/$NAV_NAME"

# Spawn session if it doesn't exist
new_session=false
if ! [ -d "$NAV_PATH" ] 2>/dev/null; then
	printf 'name=%s\ncwd=%s\nagent=partner\n' "$NAV_NAME" "$cwd" | try tee "$OLLIE/s/new" >/dev/null
	sleep 0.5
	new_session=true
fi

# Gather context from acme window (if running inside one)
context=""
if [ -n "${winid:-}" ] && [ "$winid" != "0" ]; then
	filename=$(9p read acme/$winid/tag | awk '{print $1; exit}')

	# Read selection (dot)
	sel=$(9p read acme/$winid/rdsel 2>/dev/null || true)

	# Git diff for this file (unstaged changes)
	diff=$(cd "$cwd" && git diff -- "$filename" 2>/dev/null | head -100 || true)

	context="File: $filename"
	[ -n "$sel" ] && context="$context\n\nSelection:\n$sel"
	[ -n "$diff" ] && context="$context\n\nRecent changes (git diff):\n$diff"
else
	# No acme window context; just send cwd info
	diff=$(cd "$cwd" && git diff --stat HEAD 2>/dev/null | head -30 || true)
	context="Working directory: $cwd"
	[ -n "$diff" ] && context="$context\n\nRecent changes:\n$diff"
fi

# Send prompt to Navigator
if [ "$new_session" = "true" ]; then
	printf '%b' "$context\n\nAcknowledge context. What are we working on?" | try tee "$NAV_PATH/prompt" >/dev/null
else
	printf '%b' "$context\n\nCheck in." | try tee "$NAV_PATH/prompt" >/dev/null
fi

# Wait for agent to finish, then print response
waitstate() { cat "$NAV_PATH/statewait" 2>/dev/null || { ollie-remount && cat "$NAV_PATH/statewait"; } || die "mount lost"; }
while [ "$(waitstate)" = "idle" ]; do :; done
while [ "$(waitstate)" != "idle" ]; do :; done
sleep 0.1
offset=$(try cat "$NAV_PATH/offset") || die "cannot read offset"
try tail -c +$((offset + 1)) "$NAV_PATH/chat"
printf '\n%s\n' "$NAV_NAME"
