SHELL := /bin/zsh
COMPOSE_DEV := docker compose -f docker-compose.yml
COMPOSE_PROD := docker compose -f docker-compose.prod.yml
APP_SERVICE := web
NODE_SERVICE := node

.PHONY: help install install-dev install-js migrate migrate-prod makemigrations superuser run shell test test-cov lint format check css-build css-watch collectstatic collectstatic-prod worker beat seed reindex-repository-search reset-db dev-start dev-stop prod-start prod-stop prod-deploy compose-dev-up compose-dev-down compose-dev-logs compose-dev-ps compose-dev-rebuild trust-ca compose-prod-up compose-prod-down compose-prod-logs compose-prod-ps compose-prod-rebuild deploy-init redeploy deploy-css-build deploy-seed deploy-seed-heavy deploy-seed-rims deploy-migrate-repository deploy-reindex-repository-search migrate-moodle-local deploy-migrate-moodle deploy-configure-moodle-sso deploy-migrate-smehub deploy-logs deploy-status deploy-shell clean

help:
	@echo "Available targets:"
	@echo "  install             Install base Python requirements in dev app container"
	@echo "  install-dev         Install dev Python requirements in dev app container"
	@echo "  install-js          Install Node dependencies in dev node container"
	@echo "  dev-start           Start full dev stack (web, postgres, redis, celery, flower, tailwind watcher)"
	@echo "  dev-stop            Stop dev stack"
	@echo "  migrate             Apply migrations in dev app container"
	@echo "  migrate-prod        Apply migrations in prod app container"
	@echo "  makemigrations      Generate migrations in dev app container"
	@echo "  superuser           Create superuser in dev app container"
	@echo "  run                 Alias for dev-start"
	@echo "  shell               Open Django shell in dev app container"
	@echo "  test                Run pytest in dev app container"
	@echo "  test-cov            Run pytest coverage in dev app container"
	@echo "  lint                Run Ruff in dev app container"
	@echo "  format              Run Black + Ruff --fix in dev app container"
	@echo "  check               Run Django checks in dev app container"
	@echo "  css-build           Build Tailwind CSS in dev node container"
	@echo "  css-watch           Watch Tailwind CSS in dev node container"
	@echo "  collectstatic       Collect static in dev app container"
	@echo "  collectstatic-prod  Collect static in prod app container"
	@echo "  worker              Start dev celery_worker service"
	@echo "  beat                Start dev celery_beat service"
	@echo "  seed                Run seed_all (demo volume) in dev app container"
	@echo "  reindex-repository-search  Rebuild Repository FTS vectors in dev (ARGS=\"--missing-only\")"
	@echo "  reset-db            Wipe postgres volume, re-migrate, seed_all --volume heavy"
	@echo "  prod-start          Start production compose stack"
	@echo "  prod-stop           Stop production compose stack"
	@echo "  prod-deploy         Rebuild prod stack, migrate, collectstatic, bring services up"
	@echo "  compose-dev-up      Start development Docker Compose stack"
	@echo "  compose-dev-down    Stop development Docker Compose stack"
	@echo "  compose-dev-logs    Tail logs (development stack)"
	@echo "  compose-dev-ps      Show development stack service status"
	@echo "  compose-dev-rebuild Rebuild and restart development stack"
	@echo "  trust-ca            Trust Caddy dev CA so https://moodle.local + iilmp.local validate (macOS)"
	@echo "  compose-prod-up      Start production-profile Docker Compose stack"
	@echo "  compose-prod-down    Stop production-profile Docker Compose stack"
	@echo "  compose-prod-logs    Tail logs (production stack)"
	@echo "  compose-prod-ps      Show production stack service status"
	@echo "  compose-prod-rebuild Rebuild and restart production stack"
	@echo "  deploy-init         Bootstrap remote server (clone repo, sync .env)"
	@echo "  redeploy            Pull current branch on remote and rebuild prod stack (incl. Tailwind)"
	@echo "  deploy-css-build    Rebuild Tailwind CSS + collectstatic on remote (no full redeploy)"
	@echo "  deploy-seed         Run seed_all --volume demo on remote (with y/N prompt)"
	@echo "  deploy-seed-heavy   Run seed_all --volume heavy on remote (with y/N prompt)"
	@echo "  deploy-seed-rims    Re-seed RIMS only on remote (bypasses seed_all error swallowing)"
	@echo "  deploy-migrate-repository  Wipe + re-import the legacy Repository on remote (dump + ~2.5GB PDFs)"
	@echo "  deploy-reindex-repository-search  Rebuild Repository FTS vectors on remote (ARGS=\"--missing-only\")"
	@echo "  migrate-moodle-local       Restore legacy Moodle (dump + filedir) into the local dockerized Moodle"
	@echo "  deploy-migrate-moodle      Native-restore legacy Moodle into prod moodle service (DB + ~1GB filedir)"
	@echo "  deploy-configure-moodle-sso  Wire 'Log in with IILMP' SSO + MEL WS token on remote (idempotent)"
	@echo "  deploy-migrate-smehub      Import legacy SME-Hub EHC + UltimatePOS on remote (ephemeral MariaDB x2)"
	@echo "  deploy-logs         Tail prod docker compose logs on remote"
	@echo "  deploy-status       Show prod docker compose service status on remote"
	@echo "  deploy-shell        Open interactive shell in remote web container"
	@echo "  clean         Remove caches and local build artifacts"

dev-start:
	$(COMPOSE_DEV) up -d
	@WEB_PORT=$$($(COMPOSE_DEV) port $(APP_SERVICE) 8000 2>/dev/null | awk -F: 'NF{print $$NF; exit}'); \
	if [ -z "$$WEB_PORT" ] || [ "$$WEB_PORT" = "0" ]; then \
		WEB_PORT=$${WEB_HOST_PORT:-8000}; \
	fi; \
	echo "Waiting for web on http://localhost:$$WEB_PORT ..."; \
	for i in $$(seq 1 300); do \
		if curl -fsS "http://localhost:$$WEB_PORT/accounts/login/" >/dev/null; then \
			echo "Web is ready at http://localhost:$$WEB_PORT/"; \
			exit 0; \
		fi; \
		sleep 1; \
	done; \
	echo "Web did not become ready in time on http://localhost:$$WEB_PORT/" >&2; \
	$(COMPOSE_DEV) logs --tail=80 $(APP_SERVICE); \
	exit 1

dev-stop:
	$(COMPOSE_DEV) down

install:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) pip install -r requirements/base.txt

install-dev:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) pip install -r requirements/development.txt

install-js:
	$(COMPOSE_DEV) run --rm $(NODE_SERVICE) npm install

migrate:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py migrate

migrate-prod:
	$(COMPOSE_PROD) run --rm $(APP_SERVICE) python manage.py migrate

makemigrations:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py makemigrations

superuser:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py createsuperuser

run:
	$(MAKE) dev-start

shell:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py shell

test:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) pytest

test-cov:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) pytest --cov=apps --cov-report=term-missing

lint:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) ruff check .

format:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) sh -c "black . && ruff check . --fix"

check:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py check

css-build:
	$(COMPOSE_DEV) run --rm $(NODE_SERVICE) npm run build:css

css-watch:
	$(COMPOSE_DEV) run --rm $(NODE_SERVICE) npm run watch:css

collectstatic:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py collectstatic --noinput

collectstatic-prod:
	$(COMPOSE_PROD) run --rm $(APP_SERVICE) python manage.py collectstatic --noinput

worker:
	$(COMPOSE_DEV) up -d celery_worker

beat:
	$(COMPOSE_DEV) up -d celery_beat

seed:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py seed_all --volume demo

reindex-repository-search:
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py reindex_repository_search $(ARGS)

reset-db:
	@printf "This will WIPE the local postgres volume. Continue? [y/N] " && read ans && [ "$$ans" = "y" ] || (echo "Aborted." && exit 1)
	@echo ">> Stopping web + celery + flower services..."
	$(COMPOSE_DEV) stop web celery_worker celery_beat flower || true
	$(COMPOSE_DEV) rm -f web celery_worker celery_beat flower || true
	@echo ">> Bringing whole stack down with -v (wipes postgres_data volume)..."
	$(COMPOSE_DEV) down -v --remove-orphans
	@echo ">> Starting postgres + redis fresh..."
	$(COMPOSE_DEV) up -d postgres redis
	@echo ">> Waiting for postgres to be healthy..."
	@for i in $$(seq 1 60); do \
		STATE=$$($(COMPOSE_DEV) ps --format json postgres 2>/dev/null | grep -o '"Health":"[^"]*"' | head -1 | cut -d'"' -f4); \
		if [ "$$STATE" = "healthy" ]; then echo "  postgres healthy."; break; fi; \
		sleep 1; \
	done
	@echo ">> Ensuring pgvector extension..."
	$(COMPOSE_DEV) exec -T postgres psql -U $${DB_USER:-iilmp} -d $${DB_NAME:-iilmp} -c "CREATE EXTENSION IF NOT EXISTS vector;"
	@echo ">> Running migrations..."
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py migrate --noinput
	@echo ">> Running orchestrated seed (heavy volume) — expect 5-15 min..."
	$(COMPOSE_DEV) run --rm $(APP_SERVICE) python manage.py seed_all --volume heavy
	@echo ">> Bringing full stack up..."
	$(COMPOSE_DEV) up -d
	@echo ">> reset-db complete. Visit http://localhost:$${WEB_HOST_PORT:-8000}/"

prod-start:
	$(COMPOSE_PROD) up -d

prod-stop:
	$(COMPOSE_PROD) down

prod-deploy:
	$(COMPOSE_PROD) up -d --build postgres redis web celery_worker celery_beat
	$(MAKE) migrate-prod
	$(MAKE) collectstatic-prod
	$(COMPOSE_PROD) up -d web celery_worker celery_beat nginx

compose-dev-up:
	$(COMPOSE_DEV) up -d

compose-dev-down:
	$(COMPOSE_DEV) down

compose-dev-logs:
	$(COMPOSE_DEV) logs -f --tail=200

compose-dev-ps:
	$(COMPOSE_DEV) ps

compose-dev-rebuild:
	$(COMPOSE_DEV) up -d --build

# Trust Caddy's dev-only internal CA so https://moodle.local and https://iilmp.local
# validate in the browser (no NET::ERR_CERT_AUTHORITY_INVALID). Moodle pins wwwroot to
# https + sslproxy, so SSO ("Log in with IILMP") only works over TLS — plain HTTP
# (localhost:8081) 303-redirects back to https://moodle.local. This is the supported way
# to reach Moodle in dev. macOS only; prompts once for your sudo password.
trust-ca:
	@echo "Extracting Caddy internal root CA..."
	$(COMPOSE_DEV) exec -T caddy cat /data/caddy/pki/authorities/local/root.crt > /tmp/caddy-root.crt
	@echo "Adding to macOS System keychain (you'll be prompted for your password)..."
	sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/caddy-root.crt
	@echo "Done. Fully quit and reopen Chrome, then visit https://moodle.local (and https://iilmp.local)."

compose-prod-up:
	$(COMPOSE_PROD) up -d

compose-prod-down:
	$(COMPOSE_PROD) down

compose-prod-logs:
	$(COMPOSE_PROD) logs -f --tail=200

compose-prod-ps:
	$(COMPOSE_PROD) ps

compose-prod-rebuild:
	$(COMPOSE_PROD) up -d --build

deploy-init:
	@bash scripts/deploy.sh init

redeploy:
	@bash scripts/deploy.sh redeploy

deploy-css-build:
	@bash scripts/deploy.sh css-build

deploy-seed:
	@bash scripts/deploy.sh seed demo

deploy-seed-heavy:
	@bash scripts/deploy.sh seed heavy

deploy-seed-rims:
	@bash scripts/deploy.sh seed-rims

deploy-migrate-repository:
	@bash scripts/deploy.sh migrate-repository

deploy-reindex-repository-search:
	@bash scripts/deploy.sh reindex-repository-search $(ARGS)

migrate-moodle-local:
	@bash scripts/migrate_moodle_into_docker.sh

deploy-migrate-moodle:
	@bash scripts/deploy.sh migrate-moodle

deploy-configure-moodle-sso:
	@bash scripts/deploy.sh configure-moodle-sso

deploy-migrate-smehub:
	@bash scripts/deploy.sh migrate-smehub

deploy-logs:
	@bash scripts/deploy.sh logs

deploy-status:
	@bash scripts/deploy.sh status

deploy-shell:
	@bash scripts/deploy.sh shell

clean:
	rm -rf .pytest_cache .ruff_cache htmlcov staticfiles
