# Personal Internet Cell - Makefile
# Provides easy commands for managing the cell

.PHONY: help start stop restart status logs clean setup check-deps init-peers \
        update reinstall uninstall \
        build build-api build-webui \
        start-dns start-api start-wg start-webui \
        backup restore \
        test test-all test-unit test-coverage test-api test-cli \
        test-phase1 test-phase2 test-phase3 test-phase4 test-all-phases \
        test-integration test-integration-readonly \
        show-routes add-peer list-peers

# Detect docker compose command (v2 plugin preferred, fallback to v1 standalone)
DC := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose")

# Default target
help:
	@echo "Personal Internet Cell - Management Commands"
	@echo ""
	@echo "First install:"
	@echo "  check-deps     - Install all required system packages (python3, docker, etc.)"
	@echo "  setup          - Generate keys, write configs, create data dirs"
	@echo "                   Env vars: CELL_NAME=mycell  CELL_DOMAIN=cell  VPN_ADDRESS=10.0.0.1/24  WG_PORT=51820"
	@echo "  init-peers     - Reset peer list to empty"
	@echo ""
	@echo "Lifecycle:"
	@echo "  start          - Start all services"
	@echo "  stop           - Stop all services"
	@echo "  restart        - Restart all services"
	@echo "  status         - Show container status + API health"
	@echo "  logs           - Follow logs from all services"
	@echo "  logs-<svc>     - Follow logs for one service  (e.g. make logs-api)"
	@echo "  shell-<svc>    - Open shell in a container   (e.g. make shell-api)"
	@echo ""
	@echo "Updates & reinstall:"
	@echo "  update         - git pull + rebuild + restart (deploy latest code)"
	@echo "  reinstall      - Full wipe and fresh install from current git checkout"
	@echo "  uninstall      - Stop + remove containers; prompts whether to also delete data"
	@echo ""
	@echo "Build:"
	@echo "  build          - Rebuild API image"
	@echo "  build-api      - Rebuild API image (no cache)"
	@echo "  build-webui    - Rebuild Web UI image (no cache)"
	@echo ""
	@echo "Individual services:"
	@echo "  start-dns      - Start DNS only"
	@echo "  start-api      - Start API only"
	@echo "  start-wg       - Start WireGuard only"
	@echo ""
	@echo "Maintenance:"
	@echo "  backup         - Backup config + data to backups/"
	@echo "  restore        - List available backups"
	@echo "  clean          - Remove containers and volumes (keeps config/data dirs)"
	@echo ""
	@echo "Tests:"
	@echo "  test           - Run all tests"
	@echo "  test-coverage          - Run tests with HTML coverage report"
	@echo "  test-integration       - Full integration tests (needs running stack)"
	@echo "  test-integration-readonly - Read-only integration tests (safe to run anytime)"
	@echo ""
	@echo "Peers:"
	@echo "  list-peers     - List configured WireGuard peers"
	@echo "  show-routes    - Show WireGuard routing table"

# ── Dependencies & setup ──────────────────────────────────────────────────────

check-deps:
	@sudo sh scripts/check_deps.sh

setup: check-deps
	@echo "Setting up Personal Internet Cell..."
	@sudo chown -R $$(id -u):$$(id -g) config/ data/ 2>/dev/null || true
	CELL_NAME=$(or $(CELL_NAME),mycell) \
	CELL_DOMAIN=$(or $(CELL_DOMAIN),cell) \
	VPN_ADDRESS=$(or $(VPN_ADDRESS),10.0.0.1/24) \
	WG_PORT=$(or $(WG_PORT),51820) \
	WG_PRIVATE_KEY="$(WG_PRIVATE_KEY)" \
	WG_PUBLIC_KEY="$(WG_PUBLIC_KEY)" \
	python3 scripts/setup_cell.py

init-peers:
	@echo "Initializing peer configuration..."
	@echo '[]' > data/api/peers.json
	@echo "Peer configuration initialized."

# ── Lifecycle ─────────────────────────────────────────────────────────────────

start:
	@echo "Starting Personal Internet Cell..."
	PUID=$$(id -u) PGID=$$(id -g) $(DC) up -d --build
	@echo "Services started. Check status with 'make status'"

stop:
	@echo "Stopping Personal Internet Cell..."
	PUID=$$(id -u) PGID=$$(id -g) $(DC) down
	@echo "Services stopped."

restart:
	@echo "Restarting Personal Internet Cell..."
	PUID=$$(id -u) PGID=$$(id -g) $(DC) restart
	@echo "Services restarted."

status:
	@echo "Personal Internet Cell Status:"
	@echo "================================"
	$(DC) ps
	@echo ""
	@echo "API Status:"
	@curl -s http://localhost:3000/health || echo "API not responding"

logs:
	$(DC) logs -f

logs-%:
	$(DC) logs -f $*

shell-%:
	docker exec -it cell-$* /bin/bash 2>/dev/null || docker exec -it cell-$* /bin/sh

# ── Updates & reinstall ───────────────────────────────────────────────────────

update:
	@echo "Pulling latest code..."
	git pull
	@if [ ! -f config/mail/mailserver.env ]; then \
	  echo "Config missing — running setup first..."; \
	  $(MAKE) setup; \
	fi
	@echo "Rebuilding and restarting services..."
	PUID=$$(id -u) PGID=$$(id -g) $(DC) up -d --build
	@echo "Update complete. Run 'make status' to verify."

reinstall:
	@echo "Reinstalling Personal Internet Cell from scratch..."
	PUID=$$(id -u) PGID=$$(id -g) $(DC) down -v 2>/dev/null || true
	@sudo rm -rf config/ data/
	@$(MAKE) setup
	@$(MAKE) start
	@echo "Reinstall complete."

uninstall:
	@echo ""
	@echo "This will stop and remove all containers."
	@echo ""
	@printf "Also delete config/ and data/? This cannot be undone. [y/N/cancel]: "; \
	read ans; \
	case "$$ans" in \
	  y|Y) \
	    echo "Stopping containers and removing images..."; \
	    PUID=$$(id -u) PGID=$$(id -g) $(DC) down -v --rmi all 2>/dev/null || true; \
	    echo "Deleting config/ and data/..."; \
	    sudo rm -rf config/ data/; \
	    echo "Uninstall complete. Git repo and scripts remain."; \
	    ;; \
	  n|N|"") \
	    echo "Stopping and removing containers (keeping images and data)..."; \
	    PUID=$$(id -u) PGID=$$(id -g) $(DC) down 2>/dev/null || true; \
	    echo "Done. Images, config/ and data/ are untouched. Run 'make start' to bring it back up."; \
	    ;; \
	  *) \
	    echo "Cancelled."; \
	    ;; \
	esac

# ── Build ─────────────────────────────────────────────────────────────────────

build:
	@echo "Building API service..."
	$(DC) build api

build-api:
	@echo "Rebuilding API (no cache)..."
	$(DC) build --no-cache api
	$(DC) up -d api

build-webui:
	@echo "Rebuilding Web UI (no cache)..."
	$(DC) build --no-cache webui
	$(DC) up -d webui

# ── Individual services ───────────────────────────────────────────────────────

start-dns:
	$(DC) up -d dns

start-api:
	$(DC) up -d api

start-wg:
	$(DC) up -d wireguard

start-webui:
	$(DC) up -d webui

# ── Maintenance ───────────────────────────────────────────────────────────────

clean:
	@echo "Removing containers and volumes..."
	$(DC) down -v
	docker system prune -f
	@echo "Done. config/ and data/ are untouched."

backup:
	@echo "Creating backup..."
	@mkdir -p backups
	@sudo tar -czf backups/cell-backup-$(shell date +%Y%m%d-%H%M%S).tar.gz \
		config/ data/ docker-compose.yml Makefile README.md
	@sudo chown $$(id -u):$$(id -g) backups/cell-backup-*.tar.gz
	@echo "Backup created in backups/."

restore:
	@echo "Available backups:"
	@ls -lh backups/cell-backup-*.tar.gz 2>/dev/null || echo "No backups found."
	@echo ""
	@echo "To restore: tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz"

# ── Tests ─────────────────────────────────────────────────────────────────────

test:
	@echo "Running all tests..."
	pytest tests/ api/tests/

test-all:
	python3 api/tests/run_tests.py

test-unit:
	pytest tests/

test-coverage:
	pytest tests/ api/tests/ --cov=api --cov-report=html --cov-report=term-missing --cov-fail-under=70 -v

test-integration:
	@echo "Running full integration tests (requires running PIC stack)..."
	PIC_HOST=$${PIC_HOST:-localhost} pytest tests/integration/ -v

test-integration-readonly:
	@echo "Running read-only integration tests (no peer creation)..."
	PIC_HOST=$${PIC_HOST:-localhost} pytest tests/integration/test_live_api.py tests/integration/test_webui.py -v

test-api:
	cd api && python3 -m pytest tests/test_api_endpoints.py -v

test-cli:
	cd api && python3 -m pytest tests/test_cli_tool.py -v

test-phase1:
	cd api && python3 -m pytest tests/test_network_manager.py tests/test_phase1_endpoints.py -v

test-phase2:
	cd api && python3 -m pytest tests/test_wireguard_manager.py tests/test_phase2_endpoints.py -v

test-phase3:
	cd api && python3 -m pytest tests/test_phase3_managers.py tests/test_phase3_endpoints.py -v

test-phase4:
	cd api && python3 -m pytest tests/test_phase4_routing.py tests/test_phase4_endpoints.py -v

test-all-phases:
	cd api && python3 -m pytest tests/ -v

# ── Network / peers ───────────────────────────────────────────────────────────

show-routes:
	@docker exec cell-wireguard wg show 2>/dev/null || echo "WireGuard not running"

list-peers:
	@curl -s http://localhost:3000/api/peers | python3 -m json.tool || echo "API not responding"

add-peer:
	@if [ -n "$(PEER_NAME)" ] && [ -n "$(PEER_IP)" ] && [ -n "$(PEER_KEY)" ]; then \
		curl -X POST http://localhost:3000/api/peers \
		-H "Content-Type: application/json" \
		-d '{"name":"$(PEER_NAME)","ip":"$(PEER_IP)","public_key":"$(PEER_KEY)"}'; \
	else \
		echo "Usage: make add-peer PEER_NAME=name PEER_IP=10.0.0.x PEER_KEY=<pubkey>"; \
	fi

# ── Dev ───────────────────────────────────────────────────────────────────────

dev:
	$(DC) -f docker-compose.yml -f docker-compose.dev.yml up -d
