.PHONY: all setup setup-ci setup-quality setup-molecule setup-release setup-image install update lint ansible-lint makefile-lint lint-all lint-ruff lint-format lint-bandit lint-deps typecheck checkmake install-hooks test test-unit pytest-cov molecule molecule-all test-all clean workflow-lint workflow-dryrun workflow-check install-tools check-api-identity-checks
.PHONY: configure-gitea-pypi
.PHONY: create-task create-pr push-with-pr git-push
.PHONY: check-docs docs-check

PYTHON := python3
VENV := .venv
BIN := $(VENV)/bin
CHECKMAKE := $(shell command -v checkmake 2>/dev/null || echo $(HOME)/go/bin/checkmake)

all: setup

# --- devx.mak include (shared Makefile targets) -------------------------------
# Set DEVX_PYTHON before including devx.mak so it uses the venv Python.
DEVX_PYTHON := $(BIN)/python
DEVX_VENV := $(VENV)
DEVX_BIN := $(BIN)
DEVX_COV_PKG := src/grm
DEVX_TEST_PATHS := tests/ scripts/tests/
DEVX_LINT_PATHS := src/ scripts/ tests/

# Include shared targets from devx package (create-task, create-pr, push-with-pr,
# check-config, workflow-lint, lint-ruff, clean, venv, .env, activate-scripts,
# install-hooks, install-tools, configure-gitea-pypi, checkmake, etc.)
# Silent if devx not installed yet — run 'make setup' first.
DEVX_MAK := $(shell $(BIN)/python -c \
	"from pathlib import Path; import devx; print(Path(devx.__file__).parent / 'make' / 'devx.mak')" \
	2>/dev/null)
# Fallback: when the venv doesn't exist yet, try system python3 or /opt/venv.
# In CI, /opt/venv has devx pre-installed; locally, devx may be in system python.
ifeq ($(strip $(DEVX_MAK)),)
DEVX_MAK := $(shell python3 -c \
	"from pathlib import Path; import devx; print(Path(devx.__file__).parent / 'make' / 'devx.mak')" \
	2>/dev/null)
endif
ifeq ($(strip $(DEVX_MAK)),)
DEVX_MAK := $(shell /opt/venv/bin/python -c \
	"from pathlib import Path; import devx; print(Path(devx.__file__).parent / 'make' / 'devx.mak')" \
	2>/dev/null)
endif
-include $(DEVX_MAK)

# Full setup for local development (all deps, tools, collections, hooks)
# devx is installed via pip install -e .[dev] (devx is in dev extra)
setup: $(VENV)/bin/activate .env activate-scripts configure-gitea-pypi
	@$(PIP_INSTALL) install -e '.[dev]'
	@$(BIN)/python -m devx.tools.install_checkmake
	@$(BIN)/python -m devx.tools.install_tools
	@export PATH="$(HOME)/.local/bin:$$PATH"; \
	$(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install

# Lean setup for CI jobs that need pytest + lint tools + runtime deps
# (validate job steps: detect-changes, discover-runners, pr-review;
#  release-and-maintain job steps: sync-wiki, badges)
# badges step runs generate_badges.py which needs ruff, pyright, bandit
setup-ci: $(VENV)/bin/activate .env configure-gitea-pypi
	@$(PIP_INSTALL) install -e '.[ci,lint]'
	@$(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install --no-ansible-collections --no-pre-commit --no-tea-login

# Setup for the validate CI job (lint + test deps, actionlint tool)
setup-quality: $(VENV)/bin/activate .env configure-gitea-pypi
	@$(PIP_INSTALL) install -e '.[ci,lint]'
	@$(BIN)/python -m devx.tools.install_tools
	@export PATH="$(HOME)/.local/bin:$$PATH"; \
	$(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install --no-ansible-collections --no-pre-commit --no-tea-login

# Full setup for molecule testing (needs ansible, molecule, collections)
setup-molecule: $(VENV)/bin/activate .env configure-gitea-pypi
	@$(PIP_INSTALL) install -e '.[ci,molecule]'
	@$(BIN)/python -m devx.tools.install_tools
	@export PATH="$(HOME)/.local/bin:$$PATH"; \
	$(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install --no-pre-commit --no-tea-login

# Setup for release jobs (needs git-cliff, tea, and lint tools for release.py)
setup-release: $(VENV)/bin/activate .env configure-gitea-pypi
	@$(PIP_INSTALL) install -e '.[ci,lint]'
	@$(BIN)/python -m devx.tools.install_tools --tool git-cliff --tool tea
	@export PATH="$(HOME)/.local/bin:$$PATH"; \
	$(BIN)/python -m devx.tools.setup --bin "$(BIN)" --skip-install --no-ansible-collections --no-pre-commit

# Setup for pre-built image jobs (deps already in image, just link venv + install project)
# Usage: make setup-image              (runtime deps only, devx from image)
#        make setup-image EXTRAS=lint  (runtime + lint deps, e.g. ansible-lint)
#        make setup-image EXTRAS=ci,lint (runtime + ci + lint deps, upgrades devx)
# NOTE: Cannot alias to devx-setup-image because the venv must exist before
# devx.mak can be included (chicken-and-egg). This standalone target creates
# the venv symlink first, then installs the project.
setup-image:
	@if [ -d /opt/venv ]; then ln -sf /opt/venv .venv; . .venv/bin/activate; \
		_TOKEN="$$CI_GITEA_API_TOKEN"; [ -z "$$_TOKEN" ] && _TOKEN="$$DEVELOPER_GITEA_API_TOKEN"; [ -z "$$_TOKEN" ] && _TOKEN="$$CI_GITEA_TOKEN"; \
		if [ -n "$$_TOKEN" ]; then export PIP_EXTRA_INDEX_URL="https://$$CI_GITEA_USERNAME:$${_TOKEN}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/"; fi; \
		pip install -e .$(if $(EXTRAS),[$(EXTRAS)],); \
	else echo "[setup-image] /opt/venv not found — falling back to setup-ci"; $(MAKE) setup-ci; fi

# venv, .env, activate-scripts, and PIP_INSTALL are provided by devx.mak
# (devx-venv, devx-env, devx-activate-scripts, DEVX_PIP_INSTALL)
# Aliases for convenience and backward compatibility:
.PHONY: venv activate-scripts
PIP_INSTALL := $(DEVX_PIP_INSTALL)
venv: devx-venv
.env: devx-env
activate-scripts: devx-activate-scripts

install:
	@if [ -z "$(HOST)" ]; then echo "HOST is required. Example: make install HOST=192.168.1.10"; exit 1; fi
	$(BIN)/grm install $(HOST) $(if $(USER),--user $(USER),) $(if $(KEY),--key $(KEY),) $(if $(NAME),--name $(NAME),) $(if $(TOKEN),--token $(TOKEN),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

update:
	@if [ -z "$(HOST)" ]; then echo "HOST is required. Example: make update HOST=192.168.1.10"; exit 1; fi
	$(BIN)/grm update $(HOST) $(if $(USER),--user $(USER),) $(if $(KEY),--key $(KEY),) $(if $(VERSION),--version $(VERSION),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

start:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make start NAME=runner1"; exit 1; fi
	$(BIN)/grm start $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

stop:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make stop NAME=runner1"; exit 1; fi
	$(BIN)/grm stop $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

restart:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make restart NAME=runner1"; exit 1; fi
	$(BIN)/grm restart $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

enable:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make enable NAME=runner1"; exit 1; fi
	$(BIN)/grm enable $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

disable:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make disable NAME=runner1"; exit 1; fi
	$(BIN)/grm disable $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(TOKEN),--token $(TOKEN),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

status:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make status NAME=runner1"; exit 1; fi
	$(BIN)/grm status $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

remove:
	@if [ -z "$(NAME)" ]; then echo "NAME is required. Example: make remove NAME=runner1"; exit 1; fi
	$(BIN)/grm remove $(NAME) $(if $(HOST),--host $(HOST),) $(if $(USER),--user $(USER),) $(if $(TOKEN),--token $(TOKEN),) $(if $(FORCE),--force,) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

list:
	$(BIN)/grm list $(if $(NO_STATUS),--no-status,) $(if $(ASK_BECOME_PASS),--ask-become-pass,)

# --- Aliases to devx.mak targets ----------------------------------------------
lint-ruff: devx-lint-ruff
lint-format: devx-lint-format
typecheck: devx-typecheck
lint-bandit: devx-lint-bandit
lint-deps: devx-lint-deps
lint: devx-lint
checkmake: devx-checkmake
install-tools: devx-install-tools
install-hooks: devx-install-hooks
clean: devx-clean
test-unit: devx-test-unit

# Override devx-pytest-cov to cover both src/ and scripts/
pytest-cov:
	@$(BIN)/pytest $(DEVX_TEST_PATHS) -v --cov=src/grm --cov=scripts --cov-report=term-missing --cov-fail-under=100
workflow-lint: devx-workflow-lint
workflow-dryrun: devx-workflow-dryrun
workflow-check: devx-workflow-check

configure-gitea-pypi:
	_TOKEN="$$CI_GITEA_API_TOKEN"; [ -z "$$_TOKEN" ] && _TOKEN="$$DEVELOPER_GITEA_API_TOKEN"; [ -z "$$_TOKEN" ] && _TOKEN="$$CI_GITEA_TOKEN"; \
	if [ -z "$$_TOKEN" ]; then echo "[configure-gitea-pypi] Gitea API token not set — skipping (devx must be on public PyPI)"; exit 0; fi; \
	echo "[configure-gitea-pypi] Gitea PyPI registry configured (token present)."

ansible-lint:
	PATH="$(PWD)/$(BIN):$$PATH" $(BIN)/ansible-lint ansible/

makefile-lint:
	@if command -v $(CHECKMAKE) >/dev/null 2>&1 || [ -x "$(CHECKMAKE)" ]; then \
		$(CHECKMAKE) Makefile; \
	else \
		echo "checkmake not found, skipping Makefile lint"; \
	fi

lint-all: lint ansible-lint makefile-lint workflow-lint check-api-identity-checks

check-api-identity-checks:
	@$(BIN)/python -m devx.tools.check_api_identity_checks

test-integration:
	$(BIN)/pytest tests/integration/ -v --no-cov

MOLECULE := $(realpath $(BIN))/molecule
MOLECULE_BASE := cd $(CURDIR)/ansible/roles/gitea-runner && ANSIBLE_ALLOW_BROKEN_CONDITIONALS=true ANSIBLE_INJECT_INVOCATION=1 $(MOLECULE)

# Quick local test: Ubuntu 22.04 only, all scenarios
molecule:
	@set -e; for s in default multi-instance lifecycle template-content deregister update; do if [ "$$s" = "default" ]; then $(MOLECULE_BASE) test; else $(MOLECULE_BASE) test -s $$s; fi; done

# All scenarios on all supported platforms (sequential; use CI matrix for parallel execution)
molecule-all:
	@$(BIN)/python -m devx.molecule.molecule_all --bin "$(BIN)"

test: test-all

test-all: pytest-cov molecule

# --- Vikunja task and PR management (via devx.mak fragment) -------------------
# Aliases for project-specific target names
create-task: devx-create-task
create-pr: devx-create-pr
push-with-pr: devx-push-with-pr
git-push: devx-push

# --- Documentation checks (via devx.mak fragment) -----------------------------
check-docs: devx-check-docs
docs-check: devx-docs-check
