# ──────────────────────────────────────────────────────────────
#  BanGUI — Project Makefile
#
#  Compatible with both Docker Compose and Podman Compose.
#  Auto-detects which compose binary is available.
#
#  Usage:
#    make up           — start the debug stack
#    make down         — stop the debug stack
#    make build        — (re)build the backend image without starting
#    make clean        — stop, remove all containers, volumes, and local images
#    make logs         — tail logs for all debug services
#    make restart      — restart the debug stack
#    make dev-ban-test — one-command smoke test of the ban pipeline
#    make e2e          — run the Robot Framework E2E test suite
# ──────────────────────────────────────────────────────────────

COMPOSE_FILE := Docker/compose.debug.yml

# Compose project name (matches `name:` in compose.debug.yml).
PROJECT := bangui-dev

# All named volumes declared in compose.debug.yml.
# Compose prefixes them with the project name.
DEV_VOLUMES := \
	$(PROJECT)_bangui-dev-data \
	$(PROJECT)_frontend-node-modules \
	$(PROJECT)_fail2ban-dev-config \
	$(PROJECT)_fail2ban-dev-run

# Locally-built images (compose project name + service name).
# Public images (fail2ban, node) are intentionally excluded.
DEV_IMAGES := \
	$(PROJECT)_backend

# Detect available compose binary.
COMPOSE := $(shell command -v podman-compose 2>/dev/null \
             || echo "podman compose")

# Env file in the project root.
# Passed explicitly because docker compose v2 defaults to the compose file's
# directory as the project directory, not the shell's cwd.
ENV_FILE := .env
COMPOSE_OPTS := --env-file $(ENV_FILE) -f $(COMPOSE_FILE)

# Detect available container runtime (podman or docker).
RUNTIME := $(shell command -v podman 2>/dev/null || echo "docker")

.PHONY: up down build restart logs clean dev-ban-test e2e ensure-env

## Ensure .env exists with BANGUI_SESSION_SECRET set.
## Copies .env.example → .env on first run and auto-generates the secret.
ensure-env:
	@if [ ! -f .env ]; then \
	  cp .env.example .env; \
	  python3 -c "\
import re, secrets; \
content = open('.env').read(); \
secret = secrets.token_hex(32); \
content = re.sub(r'(?m)^BANGUI_SESSION_SECRET=.*', 'BANGUI_SESSION_SECRET=' + secret, content); \
open('.env', 'w').write(content); \
print('Created .env with a generated BANGUI_SESSION_SECRET.')"; \
	fi

## Start the debug stack (detached).
## Ensures log stub files exist so fail2ban can open them on first start.
## All output is logged to /data/log/make-up.log.
up: ensure-env
	@mkdir -p data/log
	@touch data/log/auth.log
	$(COMPOSE) $(COMPOSE_OPTS) up -d 2>&1 | tee data/log/make-up.log

## Stop the debug stack.
down: ensure-env
	$(COMPOSE) $(COMPOSE_OPTS) down

## (Re)build the backend image without starting containers.
build: ensure-env
	$(COMPOSE) $(COMPOSE_OPTS) build

## Restart the debug stack.
restart: down up

## Tail logs for all debug services.
logs: ensure-env
	$(COMPOSE) $(COMPOSE_OPTS) logs -f

## Stop containers, remove ALL debug volumes and locally-built images.
## The next 'make up' will rebuild images from scratch and start fresh.
clean: ensure-env
	$(COMPOSE) $(COMPOSE_OPTS) down --remove-orphans
	$(RUNTIME) volume rm $(DEV_VOLUMES) 2>/dev/null || true
	$(RUNTIME) rmi $(DEV_IMAGES) 2>/dev/null || true
	rm -rf ./data
	@echo "All debug volumes, local images, and ./data removed. Run 'make up' to rebuild and start fresh."

## Run the Robot Framework E2E test suite.
## Requires: stack up (make up), BANGUI_SESSION_SECRET env var set.
## Installs: pip install -r e2e/requirements.txt && rfbrowser init
e2e: down clean up
	@echo "Waiting 2 minutes for services to initialize..."
	@sleep 120
	@echo "Waiting for stack to be healthy..."
	@timeout=120; \
	until curl -sf http://localhost:8000/api/v1/health > /dev/null 2>&1; do \
	  sleep 5; timeout=$$((timeout-5)); \
	  if [ $$timeout -le 0 ]; then echo "Backend not healthy after 120s"; exit 1; fi; \
	done
	pip install -r e2e/requirements.txt -q
	rfbrowser init
	robot --outputdir e2e/results e2e/tests/

## One-command smoke test for the ban pipeline:
##   1. Start fail2ban, 2. write failure lines, 3. check ban status.
dev-ban-test: ensure-env
	$(COMPOSE) $(COMPOSE_OPTS) up -d fail2ban
	sleep 5
	bash Docker/simulate_failed_logins.sh
	sleep 3
	bash Docker/check_ban_status.sh
