ROOT := `git rev-parse --show-toplevel`

# Run the native balancebot sim with the console monitor.
default: sim

# Run the native balancebot sim with the console monitor.
sim:
	#!/usr/bin/env bash
	set -euo pipefail
	cd "{{ROOT}}"
	cargo run -p cu-rp-balancebot --bin balancebot-sim

# Run the balancebot sim with the monitor embedded in Bevy.
bevy:
	#!/usr/bin/env bash
	set -euo pipefail
	cd "{{ROOT}}"
	cargo run -p cu-rp-balancebot --no-default-features --features bevymon --bin balancebot-bevymon

# Download the shared scene assets used by the BalanceBot sim.
prepare-assets:
	#!/usr/bin/env bash
	set -euo pipefail
	cd "{{invocation_directory()}}"
	mkdir -p assets
	if [[ ! -f "assets/balancebot.glb" ]]; then
		echo "Downloading balancebot.glb..."
		curl --fail --location --silent --show-error --output "assets/balancebot.glb" "https://cdn.copper-robotics.com/balancebot.glb"
	fi
	if [[ ! -f "assets/skybox.ktx2" ]]; then
		echo "Downloading skybox.ktx2..."
		curl --fail --location --silent --show-error --output "assets/skybox.ktx2" "https://cdn.copper-robotics.com/skybox.ktx2"
	fi
	if [[ ! -f "assets/diffuse_map.ktx2" ]]; then
		echo "Downloading diffuse_map.ktx2..."
		curl --fail --location --silent --show-error --output "assets/diffuse_map.ktx2" "https://cdn.copper-robotics.com/diffuse_map.ktx2"
	fi

# Serve the balancebot BevyMon sim in the browser.
web:
	#!/usr/bin/env bash
	set -euo pipefail
	if ! command -v trunk >/dev/null 2>&1; then
		echo "Missing trunk. Install with: cargo install --locked trunk" >&2
		exit 1
	fi
	cd "{{invocation_directory()}}"
	just prepare-assets
	trunk serve --open

# Build a static browser bundle into dist/balancebot with hashed asset filenames.
web-dist:
	#!/usr/bin/env bash
	set -euo pipefail
	if ! command -v trunk >/dev/null 2>&1; then
		echo "Missing trunk. Install with: cargo install --locked trunk" >&2
		exit 1
	fi
	cd "{{invocation_directory()}}"
	just prepare-assets
	rm -rf dist/balancebot
	trunk build --release --public-url ./ --dist dist/balancebot
	echo "Static web bundle written to ${PWD}/dist/balancebot"

# Extract a text log using the balancebot logreader.
text-logs:
	#!/usr/bin/env bash
	set -euo pipefail
	cargo run --bin balancebot-logreader -r -- logs/balance.copper extract-text-log ../../target/debug/cu29_log_index/strings.bin

# Run fsck against the balancebot copper log.
fsck:
	#!/usr/bin/env bash
	set -euo pipefail
	cargo run --bin balancebot-logreader -r -- logs/balance.copper fsck

# dump runtime Events
fsck-runtime:
	#!/usr/bin/env bash
	set -euo pipefail
	cargo run --bin balancebot-logreader -r -- logs/balance.copper fsck --dump-runtime-lifecycle

fsck-resim:
	#!/usr/bin/env bash
	set -euo pipefail
	RUST_BACKTRACE=1 cargo run -r --bin balancebot-logreader  logs/balanceresim.copper fsck

cmp:
	#!/usr/bin/env bash
	cmp logs/balance_0.copper logs/balanceresim_0.copper

# Render a DAG with log-derived statistics. Requires explicit bin=<logreader>.
dag-stats bin="balancebot-logreader" log="logs/balance.copper" mission="" out="target/cu29_logstats.json":
	#!/usr/bin/env bash
	set -euo pipefail

	bin_name="{{bin}}"
	[[ -n "$bin_name" ]] || { echo "bin is required"; exit 1; }

	invocation_dir="{{invocation_directory()}}"
	cfg_path="${invocation_dir}/copperconfig.ron"
	if [[ ! -f "$cfg_path" ]]; then
		echo "No copperconfig.ron found in ${invocation_dir}" >&2
		exit 1
	fi

	log_path="{{log}}"
	if [[ "$log_path" != /* ]]; then
		log_path="${invocation_dir}/${log_path}"
	fi
	log_base="$log_path"
	if [[ "$log_base" == *_0.copper ]]; then
		log_base="${log_base%_0.copper}.copper"
	fi
	if [[ "$log_base" == *.copper ]]; then
		log_slab="${log_base%.copper}_0.copper"
	else
		log_slab="${log_base}_0.copper"
	fi
	[[ -f "$log_base" || -f "$log_slab" ]] || { echo "Log file not found: $log_path" >&2; exit 1; }

	out_path="{{out}}"
	if [[ "$out_path" != /* ]]; then
		out_path="${invocation_dir}/${out_path}"
	fi
	mkdir -p "$(dirname "$out_path")"

	mission_value="{{mission}}"
	if [[ -n "$mission_value" ]]; then
		(
			cd "$invocation_dir"
			cargo run --bin "$bin_name" -- "$log_base" log-stats --config "$cfg_path" --output "$out_path" --mission "$mission_value"
		)

		(
			cd "{{ROOT}}"
			cargo run -p cu29-runtime --bin cu29-rendercfg -- --logstats "$out_path" --open "$cfg_path" --mission "$mission_value"
		)
	else
		(
			cd "$invocation_dir"
			cargo run --bin "$bin_name" -- "$log_base" log-stats --config "$cfg_path" --output "$out_path"
		)

		(
			cd "{{ROOT}}"
			cargo run -p cu29-runtime --bin cu29-rendercfg -- --logstats "$out_path" --open "$cfg_path"
		)
	fi

# Set permissions on balancebot PWM sysfs entries.
balancebot-set-pwm-permissions:
	#!/usr/bin/env bash
	set -euo pipefail
	for pwm in /sys/class/pwm/pwmchip0/pwm*/; do
		chmod 0660 "${pwm}enable"
		chmod 0660 "${pwm}duty_cycle"
		chmod 0660 "${pwm}period"
		chmod 0660 "${pwm}polarity"
		chown root:wheel "${pwm}enable"
		chown root:wheel "${pwm}duty_cycle"
		chown root:wheel "${pwm}period"
		chown root:wheel "${pwm}polarity"
	done
	chmod 0660 /sys/class/pwm/pwmchip0/unexport
	chown root:wheel /sys/class/pwm/pwmchip0/unexport

# Convert the balancebot log to MCAP and show a summary.
mcap:
	#!/usr/bin/env bash
	set -euo pipefail

	copper_base="logs/balance.copper"
	mcap_file="logs/balance.mcap"

	echo "=========================================="
	echo "Converting: ${copper_base} -> ${mcap_file}"
	echo "=========================================="

	# Export to MCAP (Copper will automatically find all _0, _1, _2... slabs)
	cargo run --bin balancebot-logreader --profile screaming -- "${copper_base}" export-mcap --output "${mcap_file}"

	echo ""
	echo "=========================================="
	echo "MCAP Info for: ${mcap_file}"
	echo "=========================================="

	# Run mcap-info to show the user what was created
	cargo run --bin balancebot-logreader --profile screaming -- "${copper_base}" mcap-info "${mcap_file}"

resim:
	#!/usr/bin/env bash
	set -euo pipefail
	cargo run --bin balancebot-resim -r
