# retoor <retoor@molodetz.nl>
SHELL := /bin/bash
export PYTHONDONTWRITEBYTECODE := 1

PY := .venv/bin/python
PIP := .venv/bin/pip
STAMP := .venv/.stamp
PKG := molodetz
HOST ?= 127.0.0.1
PORT ?= 8088
WORKERS ?= 2
LOCUST_PORT ?= 8097
LOCUST_DATA := /tmp/molodetz-locust-data
SCREENSHOTS_DIR ?= $(CURDIR)/../static/pizdetz
SCREENSHOTS_PORT ?= 8094
SCREENSHOTS_STAGING_URL ?= https://staging.app.molodetz.nl
SCREENSHOTS_PRODUCTION_URL ?= https://molodetz.nl
STAGING_ADMIN_PASSWORD ?= staging-admin-pass-1
PYTEST := $(PY) -m pytest

.PHONY: install dev prod test test-headed test-unit test-api test-e2e test-fast test-failed \
	test-first-failure test-slowest test-cache-clean check-ui preflight coverage coverage-headed \
	coverage-html locust locust-headless screenshots screenshots-staging screenshots-production \
	staging-refresh prune prune-dry-run tree tree-loc zip delete-pyc clean

$(STAMP): pyproject.toml
	python3 -m venv .venv
	$(PIP) install --upgrade pip
	$(PIP) install -e ".[dev]"
	$(PY) -m playwright install chromium
	touch $(STAMP)

install: $(STAMP)
	git config core.hooksPath .githooks || true

dev: $(STAMP)
	$(PY) -m uvicorn $(PKG).main:app --host $(HOST) --port $(PORT) --reload --reload-dir $(PKG) --backlog 4096

prod: $(STAMP)
	MOLODETZ_STATIC_VERSION=$$(date +%s) MOLODETZ_TEMPLATE_AUTO_RELOAD=0 $(PY) -m uvicorn $(PKG).main:app --host $(HOST) --port $(PORT) \
		--workers $(WORKERS) --backlog 8192 --proxy-headers --forwarded-allow-ips='*'

test: $(STAMP)
	$(PYTEST)

test-headed: $(STAMP)
	PLAYWRIGHT_HEADLESS=0 PLAYWRIGHT_SLOW_MO=150 $(PYTEST)

test-unit: $(STAMP)
	$(PYTEST) tests/unit

test-api: $(STAMP)
	$(PYTEST) tests/api

test-e2e: $(STAMP)
	$(PYTEST) tests/e2e

test-fast: $(STAMP)
	$(PYTEST) tests/unit tests/api

test-failed: $(STAMP)
	$(PYTEST) --lf

test-first-failure: $(STAMP)
	$(PYTEST) -x

test-slowest: $(STAMP)
	$(PYTEST) --durations=40

test-cache-clean:
	rm -rf .pytest_cache

check-ui: $(STAMP)
	$(PY) -m $(PKG).gates

preflight: $(STAMP)
	$(PY) -c "import $(PKG).main; print('import ok')"
	$(PY) -m pyflakes $(PKG) tests
	for f in $$(find $(PKG)/static/js -name '*.js'); do node --check "$$f" 2>/dev/null || node --input-type=module --check < "$$f" || exit 1; done
	$(PY) -m $(PKG).cli system sql-lint
	$(MAKE) check-ui

coverage: $(STAMP)
	rm -f .coverage .coverage.*
	COVERAGE_PROCESS_START=$(CURDIR)/.coveragerc PYTHONPATH=$(CURDIR) $(PY) -m coverage run -m pytest
	$(PY) -m coverage combine || true
	$(PY) -m coverage report

coverage-headed: $(STAMP)
	PLAYWRIGHT_HEADLESS=0 $(MAKE) coverage

coverage-html: coverage
	$(PY) -m coverage html -d out/coverage

locust: $(STAMP)
	$(MAKE) locust-run LOCUST_ARGS=""

locust-headless: $(STAMP)
	$(MAKE) locust-run LOCUST_ARGS="--headless -u 20 -r 5 -t 120s --html out/locust.html"

locust-run:
	rm -rf $(LOCUST_DATA); mkdir -p $(LOCUST_DATA) out
	-fuser -k $(LOCUST_PORT)/tcp 2>/dev/null
	MOLODETZ_DATA_DIR=$(LOCUST_DATA) MOLODETZ_ADMIN_PASSWORD=locust-$$RANDOM$$RANDOM MOLODETZ_DISABLE_RATE_LIMIT=1 \
		$(PY) -m uvicorn $(PKG).main:app --host 127.0.0.1 --port $(LOCUST_PORT) --workers 2 & echo $$! > $(LOCUST_DATA)/server.pid
	for i in $$(seq 1 60); do curl -fs http://127.0.0.1:$(LOCUST_PORT)/health >/dev/null && break; sleep 0.5; done
	-$(PY) -m locust -f locustfile.py --host http://127.0.0.1:$(LOCUST_PORT) $(LOCUST_ARGS)
	-kill $$(cat $(LOCUST_DATA)/server.pid)
	-for i in $$(seq 1 40); do kill -0 $$(cat $(LOCUST_DATA)/server.pid) 2>/dev/null || break; sleep 0.25; done
	rm -rf $(LOCUST_DATA)

screenshots: $(STAMP)
	SCREENSHOTS_DIR=$(SCREENSHOTS_DIR) SCREENSHOTS_PORT=$(SCREENSHOTS_PORT) SCREENSHOTS_ENV=test $(PY) screenshots.py

screenshots-staging: $(STAMP)
	SCREENSHOTS_DIR=$(SCREENSHOTS_DIR) SCREENSHOTS_ENV=staging SCREENSHOTS_BASE_URL=$(SCREENSHOTS_STAGING_URL) \
		SCREENSHOTS_ADMIN_PASSWORD=$(STAGING_ADMIN_PASSWORD) $(PY) screenshots.py

screenshots-production: $(STAMP)
	SCREENSHOTS_DIR=$(SCREENSHOTS_DIR) SCREENSHOTS_ENV=production SCREENSHOTS_BASE_URL=$(SCREENSHOTS_PRODUCTION_URL) \
		SCREENSHOTS_ADMIN_PASSWORD=$(SCREENSHOTS_ADMIN_PASSWORD) $(PY) screenshots.py

staging-refresh:
	bin/staging-refresh.sh $(SNAPSHOT)

prune: $(STAMP)
	bin/maintenance.sh

prune-dry-run: $(STAMP)
	bin/maintenance.sh --dry-run

tree:
	find . -path ./.venv -prune -o -path ./.git -prune -o -path ./data -prune -o -type f -print | sort

tree-loc:
	find $(PKG) tests -name '*.py' -o -name '*.js' -not -path '*/vendor/*' -not -path '*/generated/*' | xargs wc -l | sort -n

zip:
	mkdir -p out && git archive --format=zip -o out/$(PKG).zip HEAD

delete-pyc:
	find . -path ./.venv -prune -o \( -name '__pycache__' -o -name '*.pyc' \) -exec rm -rf {} +

clean: delete-pyc
	rm -rf .venv build dist *.egg-info .pytest_cache .coverage .coverage.* out/coverage
