SHELL := /usr/bin/env bash
PYTHON ?= python3
VENV_DIR ?= .venv
PIP := $(VENV_DIR)/bin/pip
UVICORN := $(VENV_DIR)/bin/uvicorn

.PHONY: help venv install env run start stop restart run-mock run-serial reset clean

help:
	@echo "Targets:"
	@echo "  venv       - create virtual environment in $(VENV_DIR)"
	@echo "  install    - install Python dependencies"
	@echo "  env        - create .env from .env.example if missing"
	@echo "  run        - run API (uses .env)"
	@echo "  start      - start API in background (PID file: .uvicorn.pid)"
	@echo "  stop       - stop API using PID file"
	@echo "  restart    - stop then start API"
	@echo "  run-mock   - run API with APP_MODE=mock"
	@echo "  run-serial - run API with APP_MODE=serial"
	@echo "  reset      - remove virtual environment and .env"

venv:
	$(PYTHON) -m venv $(VENV_DIR)

install: venv env
	$(PIP) install --upgrade pip
	$(PIP) install -r requirements.txt

env:
	@bash -c 'set -euo pipefail; \
	if [ ! -f .env ]; then \
	  cp .env.example .env; \
	  echo ".env created from .env.example"; \
	else \
	  changed=0; \
	  while IFS= read -r line; do \
	    case "$$line" in \
	      ""|\#*) continue ;; \
	    esac; \
	    key="$${line%%=*}"; \
	    if ! grep -qE "^$${key}=" .env; then \
	      echo "$$line" >> .env; \
	      changed=1; \
	    fi; \
	  done < .env.example; \
	  if [ "$$changed" -eq 1 ]; then \
	    echo ".env updated with missing variables"; \
	  else \
	    echo ".env up to date"; \
	  fi; \
	fi'

run:
	bash -c 'set -a; [ -f .env ] && . ./.env; set +a; $(UVICORN) app.main:app --host "$${APP_HOST:-0.0.0.0}" --port "$${APP_PORT:-8000}"'

start:
	@bash -c 'set -a; [ -f .env ] && . ./.env; set +a; \
	if [ -f .uvicorn.pid ] && kill -0 "$$(cat .uvicorn.pid)" 2>/dev/null; then \
	  echo "API already running (PID $$(cat .uvicorn.pid))"; \
	  exit 0; \
	fi; \
	nohup $(UVICORN) app.main:app --host "$${APP_HOST:-0.0.0.0}" --port "$${APP_PORT:-8000}" >/dev/null 2>&1 & \
	echo $$! > .uvicorn.pid; \
	echo "API started (PID $$(cat .uvicorn.pid))"'

stop:
	@bash -c 'set -euo pipefail; \
	if [ ! -f .uvicorn.pid ]; then \
	  echo "No PID file (.uvicorn.pid)."; \
	  exit 0; \
	fi; \
	pid="$$(cat .uvicorn.pid)"; \
	if kill -0 "$$pid" 2>/dev/null; then \
	  kill "$$pid"; \
	  echo "API stopped (PID $$pid)"; \
	else \
	  echo "Process not running (PID $$pid)"; \
	fi; \
	rm -f .uvicorn.pid'

restart: stop start

run-mock:
	bash -c 'set -a; [ -f .env ] && . ./.env; set +a; APP_MODE=mock $(UVICORN) app.main:app --host "$${APP_HOST:-0.0.0.0}" --port "$${APP_PORT:-8000}"'

run-serial:
	bash -c 'set -a; [ -f .env ] && . ./.env; set +a; APP_MODE=serial $(UVICORN) app.main:app --host "$${APP_HOST:-0.0.0.0}" --port "$${APP_PORT:-8000}"'

reset:
	rm -rf $(VENV_DIR)
	rm -f .env .uvicorn.pid

clean: reset
