.PHONY: help up down rebuild logs status clean-data health psql build-engine seed-ui seed-site seed-geoip

.DEFAULT_GOAL := help

REPO_ROOT := $(realpath $(CURDIR)/../..)
ENGINE_IMAGE := galaxy-engine:dev
STACK_LABEL := galaxy.stack=dev-deploy
ENGINE_LABEL := org.opencontainers.image.title=galaxy-game-engine
# Public host the in-front host Caddy serves the single-origin stack on.
# Used only by `make health` probes; override for a different domain.
GALAXY_DEV_HOST ?= galaxy.lan
# Game-state root lives under the invoking user's home by default so
# `make up` works without sudo. Override `GALAXY_DEV_GAME_STATE_DIR`
# in the environment or `.env` to relocate (e.g. /var/lib/galaxy-dev/
# game-state in a production-shaped host). The value flows through to
# both the compose bind-mount and the backend's
# `BACKEND_GAME_STATE_ROOT`.
export GALAXY_DEV_GAME_STATE_DIR ?= $(HOME)/.galaxy-dev/game-state

COMPOSE := docker compose

help:
	@echo "Long-lived Galaxy dev environment (single-origin, e.g. https://galaxy.lan):"
	@echo "  make up             Build images, ensure engine image, seed geoip, bring stack up"
	@echo "  make rebuild        Force rebuild of backend / gateway images and bring up"
	@echo "  make build-engine   Build $(ENGINE_IMAGE) from game/Dockerfile (no-op if present)"
	@echo "  make seed-ui        Build ui/frontend and load into galaxy-dev-ui-dist volume"
	@echo "  make seed-site      Build site/ (VitePress) and load into galaxy-dev-site-dist volume"
	@echo "  make seed-geoip     Copy GeoIP fixture into galaxy-dev-geoip-data volume"
	@echo "  make down           Stop containers, keep named volumes"
	@echo "  make logs           Tail all logs"
	@echo "  make status         docker compose ps"
	@echo "  make health         Probe the stack through the host Caddy"
	@echo "  make psql           Open a psql shell as galaxy@galaxy_backend"
	@echo "  make clean-data     Stop everything and wipe named volumes + game-state"
	@echo ""
	@echo "Requires:"
	@echo "  - external Docker network '$${GALAXY_EDGE_NETWORK:-edge}'"
	@echo "    (docker network create edge)"
	@echo "  - host Caddy proxying the public host into that network"
	@echo "  - game-state dir: $(GALAXY_DEV_GAME_STATE_DIR) (auto-created)"

up: build-engine seed-geoip
	mkdir -p "$(GALAXY_DEV_GAME_STATE_DIR)"
	$(COMPOSE) up -d --wait

rebuild: build-engine seed-geoip
	$(COMPOSE) build --no-cache galaxy-backend galaxy-api
	mkdir -p "$(GALAXY_DEV_GAME_STATE_DIR)"
	$(COMPOSE) up -d --wait

build-engine:
	@if docker image inspect $(ENGINE_IMAGE) >/dev/null 2>&1; then \
		echo "$(ENGINE_IMAGE) already built; skipping (use 'docker rmi $(ENGINE_IMAGE)' to force a rebuild)."; \
	else \
		echo "building $(ENGINE_IMAGE)…"; \
		docker build -t $(ENGINE_IMAGE) -f $(REPO_ROOT)/game/Dockerfile $(REPO_ROOT); \
	fi

# Copy the GeoIP fixture into a named volume the backend mounts as
# /var/lib/galaxy. Using a volume avoids a bind-mount that would
# resolve against an ephemeral workspace path when compose is driven
# from the Gitea runner (see tools/dev-deploy/KNOWN-ISSUES.md for the
# breakage that bind-mounts caused on `docker restart`).
seed-geoip:
	@echo "seeding GeoIP fixture into galaxy-dev-geoip-data…"
	docker volume create galaxy-dev-geoip-data >/dev/null
	docker run --rm \
	  -v galaxy-dev-geoip-data:/dst \
	  -v $(REPO_ROOT)/pkg/geoip/test-data/test-data:/src:ro \
	  alpine sh -c 'cp /src/GeoIP2-Country-Test.mmdb /dst/geoip.mmdb'

# Build the UI frontend and load the resulting build/ directory into
# the named volume Caddy serves from. Used by the dev-deploy workflow
# and by anyone bringing the stack up by hand.
seed-ui:
	@if [ ! -d $(REPO_ROOT)/ui/frontend/node_modules ]; then \
		echo "installing UI dependencies…"; \
		(cd $(REPO_ROOT)/ui && pnpm install --frozen-lockfile); \
	fi
	@echo "building UI (vite build)…"
	(cd $(REPO_ROOT)/ui/frontend && \
	  VITE_GATEWAY_BASE_URL= \
	  BASE_PATH=/game \
	  VITE_GALAXY_DEV_AFFORDANCES=true \
	  VITE_GATEWAY_RESPONSE_PUBLIC_KEY=$$(cat $(REPO_ROOT)/ui/frontend/.env.development \
	      | sed -n 's/^VITE_GATEWAY_RESPONSE_PUBLIC_KEY=//p') \
	  pnpm build)
	@echo "loading build/ into galaxy-dev-ui-dist volume…"
	docker volume create galaxy-dev-ui-dist >/dev/null
	docker run --rm \
	  -v galaxy-dev-ui-dist:/dst \
	  -v $(REPO_ROOT)/ui/frontend/build:/src:ro \
	  alpine sh -c 'rm -rf /dst/* /dst/.??* 2>/dev/null; cp -a /src/. /dst/'

# Build the project site (VitePress) and load the static output into the
# named volume Caddy serves at the root. Used by the dev-deploy workflow
# and by anyone bringing the stack up by hand.
seed-site:
	@if [ ! -d $(REPO_ROOT)/site/node_modules ]; then \
		echo "installing site dependencies…"; \
		(cd $(REPO_ROOT)/site && pnpm install --frozen-lockfile); \
	fi
	@echo "building project site (vitepress build)…"
	(cd $(REPO_ROOT)/site && pnpm build)
	@echo "loading site dist into galaxy-dev-site-dist volume…"
	docker volume create galaxy-dev-site-dist >/dev/null
	docker run --rm \
	  -v galaxy-dev-site-dist:/dst \
	  -v $(REPO_ROOT)/site/.vitepress/dist:/src:ro \
	  alpine sh -c 'rm -rf /dst/* /dst/.??* 2>/dev/null; cp -a /src/. /dst/'

down:
	$(COMPOSE) down

logs:
	$(COMPOSE) logs -f --tail=100

status:
	$(COMPOSE) ps

health:
	@echo "Site (https://$(GALAXY_DEV_HOST)/):"
	@curl -sS -o /dev/null -w "  HTTP %{http_code}\n" https://$(GALAXY_DEV_HOST)/ || echo "  unreachable"
	@echo "Game (https://$(GALAXY_DEV_HOST)/game/):"
	@curl -sS -o /dev/null -w "  HTTP %{http_code}\n" https://$(GALAXY_DEV_HOST)/game/ || echo "  unreachable"
	@echo "API healthz (https://$(GALAXY_DEV_HOST)/healthz):"
	@curl -sS -o /dev/null -w "  HTTP %{http_code}\n" https://$(GALAXY_DEV_HOST)/healthz || echo "  unreachable"

psql:
	$(COMPOSE) exec galaxy-postgres psql -U galaxy -d galaxy_backend

clean-data:
	@echo "Stopping containers and engines, then wiping volumes + game-state…"
	$(COMPOSE) down -v
	@ids=$$(docker ps -aq \
		--filter "label=$(STACK_LABEL)" \
		--filter "label=$(ENGINE_LABEL)"); \
	if [ -n "$$ids" ]; then \
		echo "stopping engine containers for $(STACK_LABEL)…"; \
		docker rm -f $$ids >/dev/null; \
	fi
	@if [ -d "$(GALAXY_DEV_GAME_STATE_DIR)" ]; then \
		echo "wiping $(GALAXY_DEV_GAME_STATE_DIR)…"; \
		docker run --rm -v "$(GALAXY_DEV_GAME_STATE_DIR):/state" alpine sh -c 'rm -rf /state/*' 2>/dev/null \
			|| rm -rf "$(GALAXY_DEV_GAME_STATE_DIR)"/* 2>/dev/null || true; \
	fi
