# QA STLC Agents — Makefile
#
# Supports ADO, Jira, and Both pipelines.
#
# INTEGRATION variable controls which agents/skills/config are active.
# Override on the command line:
#   make install        INTEGRATION=jira
#   make mcp-config     INTEGRATION=both
#   make verify         INTEGRATION=jira
#
# Convenience aliases (no INTEGRATION override needed):
#   make install-ado              make install-jira              make install-both
#   make mcp-config-ado           make mcp-config-jira           make mcp-config-both
#   make mcp-config-vscode-ado    make mcp-config-vscode-jira    make mcp-config-vscode-both
#   make skills-ado               make skills-jira               make skills-both
#   make verify-ado               make verify-jira               make verify-both
#   make bootstrap-ado            make bootstrap-jira            make bootstrap-both
#   make migrate-ado              make migrate-jira              make migrate-both
#
# Migration (existing Playwright project → Helix-QA layout):
#   make migrate-preview  SOURCE=./old-tests HELIX=./helix-qa
#   make migrate          SOURCE=./old-tests HELIX=./helix-qa \
#                         [INTEGRATION=both] [CONFLICT=overwrite] \
#                         [PRESERVE_TREE=1] [FEATURES=vrt]
#   make migrate-ado      SOURCE=./old-tests HELIX=./helix-qa
#   make audit-migration  HELIX=./helix-qa

PYTHON      := python3
VENV        := .venv
PIP         := $(VENV)/bin/pip
PYTEST      := $(VENV)/bin/pytest
INTEGRATION ?= ado

# ── Agent binary paths ─────────────────────────────────────────────────────────
MCP_TC   := $(VENV)/bin/qa-test-case-manager
MCP_GH   := $(VENV)/bin/qa-gherkin-generator
MCP_PW   := $(VENV)/bin/qa-playwright-generator
MCP_HX   := $(VENV)/bin/qa-helix-writer
MCP_JR   := $(VENV)/bin/qa-jira-manager
MCP_MG   := $(VENV)/bin/qa-migration

.PHONY: \
  install install-ado install-jira install-both install-dev \
  bootstrap bootstrap-ado bootstrap-jira bootstrap-both \
  skills skills-ado skills-jira skills-both skills-vscode \
  mcp-config mcp-config-ado mcp-config-jira mcp-config-both \
  mcp-config-vscode mcp-config-vscode-ado mcp-config-vscode-jira mcp-config-vscode-both \
  verify verify-ado verify-jira verify-both \
  serve serve-prod \
  install-webhook \
  docker-build-webhook docker-run-webhook \
  register-ado-hooks register-jira-hooks register-hooks \
  deploy-azure \
  test test-webhook test-all \
  publish clean \
  help \
  migrate migrate-ado migrate-jira migrate-both \
  migrate-preview migrate-help audit-migration

# ─── Default target ────────────────────────────────────────────────────────────
.DEFAULT_GOAL := help

help: ## Show this help
	@echo ""
	@echo "QA STLC Agents — available targets"
	@echo ""
	@echo "  INTEGRATION=[ado|jira|both]  (default: ado)"
	@echo ""
	@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) \
	  | sed 's/:.*##/\t/' \
	  | column -t -s $$'\t' \
	  | sed 's/^/  /'
	@echo ""

# ─── Install ───────────────────────────────────────────────────────────────────
install: ## Create venv and install all five MCP agents
	$(PYTHON) -m venv $(VENV)
	$(PIP) install --upgrade pip
	$(PIP) install -e .
	@mkdir -p . && cp ORCHESTRATION_RULES.md . 2>/dev/null || true
	@echo ""
	@echo "✓ All six MCP agents installed"
	@echo "  ADO  entry point  : $(MCP_TC)"
	@echo "  Jira entry point  : $(MCP_JR)"
	@echo "  Shared (both)     : $(MCP_GH)"
	@echo "                      $(MCP_PW)"
	@echo "                      $(MCP_HX)"
	@echo "  Migration         : $(MCP_MG)  (stlc-migrate CLI also available)"
	@echo ""
	@echo "  Rules file        : ORCHESTRATION_RULES.md (project root)"
	@echo "Active integration  : $(INTEGRATION)"
	@$(MAKE) --no-print-directory _next_steps_$(INTEGRATION)

install-ado:  ## Install for ADO integration
	@$(MAKE) install INTEGRATION=ado

install-jira: ## Install for Jira integration
	@$(MAKE) install INTEGRATION=jira

install-both: ## Install for both ADO and Jira
	@$(MAKE) install INTEGRATION=both

install-dev: install ## Install + pytest for local development
	$(PIP) install pytest pytest-asyncio

install-webhook: ## Install webhook bridge extra deps (FastAPI + uvicorn)
	$(PIP) install -e ".[webhook]"

# ─── Internal next-step hints ──────────────────────────────────────────────────
_next_steps_ado:
	@echo "Next steps:"
	@echo "  make bootstrap-ado                              # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo ""
	@echo "  # Greenfield:"
	@echo "  qa-stlc scaffold --name my-qa-project           # new Playwright + Cucumber + TS project"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-ado SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

_next_steps_jira:
	@echo "Next steps:"
	@echo "  make bootstrap-jira                             # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo "  Add JIRA_CLIENT_ID / JIRA_CLIENT_SECRET / JIRA_CLOUD_ID to .env"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-jira SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

_next_steps_both:
	@echo "Next steps:"
	@echo "  make bootstrap-both                             # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo "  Add JIRA_CLIENT_ID / JIRA_CLIENT_SECRET / JIRA_CLOUD_ID to .env"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-both SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

# ─── Bootstrap (skills + MCP config in one shot) ───────────────────────────────
bootstrap: ## Install skills + MCP config (Claude Code + VS Code) — INTEGRATION=ado|jira|both
	@$(MAKE) --no-print-directory skills          INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory skills-vscode   INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory mcp-config      INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory mcp-config-vscode INTEGRATION=$(INTEGRATION)
	@echo ""
	@echo "✓ Bootstrap complete (integration=$(INTEGRATION))"

bootstrap-ado:  ## skills + MCP config for ADO (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=ado

bootstrap-jira: ## skills + MCP config for Jira (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=jira

bootstrap-both: ## skills + MCP config for both (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=both

# ─── Verify ────────────────────────────────────────────────────────────────────
verify: ## Verify agent binaries and auth caches (INTEGRATION=ado|jira|both)
	@echo "=== Verifying integration: $(INTEGRATION) ==="
ifeq ($(INTEGRATION),ado)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_ado_auth
else ifeq ($(INTEGRATION),jira)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_jira_auth
else ifeq ($(INTEGRATION),both)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_ado_auth
	@$(MAKE) --no-print-directory _verify_jira_auth
else
	@echo "Unknown INTEGRATION=$(INTEGRATION). Use ado, jira, or both." && exit 1
endif

_verify_shared:
	@echo "--- Shared agents ---"
	@test -f $(MCP_GH) && echo "✓ $(MCP_GH)" || echo "✗ $(MCP_GH) not found — run: make install"
	@test -f $(MCP_PW) && echo "✓ $(MCP_PW)" || echo "✗ $(MCP_PW) not found — run: make install"
	@test -f $(MCP_HX) && echo "✓ $(MCP_HX)" || echo "✗ $(MCP_HX) not found — run: make install"
	@test -f $(MCP_MG) && echo "✓ $(MCP_MG)" || echo "✗ $(MCP_MG) not found — run: make install"

_verify_ado_auth:
	@echo "--- ADO agent + MSAL auth ---"
	@test -f $(MCP_TC) && echo "✓ $(MCP_TC)" || echo "✗ $(MCP_TC) not found — run: make install"
	@$(PYTHON) -c \
	  "from stlc_agents.shared.auth import get_signed_in_user; \
	   u = get_signed_in_user(); \
	   print('✓ ADO MSAL: signed in as ' + u if u else \
	         '⚠ ADO MSAL: no cached account — browser opens on first tool call')" \
	  2>/dev/null || echo "⚠ ADO MSAL: auth module not found — run: make install"

_verify_jira_auth:
	@echo "--- Jira agent + OAuth cache ---"
	@test -f $(MCP_JR) && echo "✓ $(MCP_JR)" || echo "✗ $(MCP_JR) not found — run: make install"
	@test -f ~/.jira-cache/jira-token.json \
	  && echo "✓ Jira token cache found" \
	  || echo "⚠ Jira token cache not found — browser opens on first qa-jira-manager call"
	@test -n "$$JIRA_CLIENT_ID" \
	  && echo "✓ JIRA_CLIENT_ID set" \
	  || echo "⚠ JIRA_CLIENT_ID not set in env / .env"

verify-ado:  ## Verify ADO integration
	@$(MAKE) verify INTEGRATION=ado

verify-jira: ## Verify Jira integration
	@$(MAKE) verify INTEGRATION=jira

verify-both: ## Verify both integrations
	@$(MAKE) verify INTEGRATION=both

# ─── Skills ────────────────────────────────────────────────────────────────────
# ADO skill set
ADO_SKILL_DIRS  = generate-test-cases generate-gherkin generate-playwright-code \
                  write-helix-files deduplication-protocol migrate-framework

# Jira skill set (qa-jira-manager replaces generate-test-cases)
JIRA_SKILL_DIRS = qa-jira-manager generate-gherkin generate-playwright-code \
                  write-helix-files deduplication-protocol migrate-framework

# Common reference files (installed to all skill destinations)
# • ORCHESTRATION_RULES.md — reference guide for multi-step QA workflows
# • AGENT-BEHAVIOR.md      — agent decision rules and routing logic

skills: ## Install skills to .claude/skills/ (Claude Code)
	node ./bin/qa-stlc.js skills --target claude --integration $(INTEGRATION)

skills-vscode: ## Install skills to .github/copilot-instructions/ (VS Code / Copilot)
	node ./bin/qa-stlc.js skills --target vscode --integration $(INTEGRATION)

skills-ado:  ## Install ADO skills (Claude Code + VS Code)
	node ./bin/qa-stlc.js skills --target both --integration ado

skills-jira: ## Install Jira skills (Claude Code + VS Code)
	node ./bin/qa-stlc.js skills --target both --integration jira

skills-both: ## Install all skills (Claude Code + VS Code)
	node ./bin/qa-stlc.js skills --target both --integration both

# ─── MCP Config ────────────────────────────────────────────────────────────────
mcp-config: ## Write .mcp.json for Claude Code (INTEGRATION=ado|jira|both)
	node ./bin/qa-stlc.js mcp-config --integration $(INTEGRATION)

mcp-config-ado:  ## Write .mcp.json for ADO
	@$(MAKE) mcp-config INTEGRATION=ado

mcp-config-jira: ## Write .mcp.json for Jira
	@$(MAKE) mcp-config INTEGRATION=jira

mcp-config-both: ## Write .mcp.json for both ADO and Jira
	@$(MAKE) mcp-config INTEGRATION=both

mcp-config-vscode: ## Write .vscode/mcp.json for VS Code / Copilot (INTEGRATION=ado|jira|both)
	node ./bin/qa-stlc.js mcp-config --vscode --integration $(INTEGRATION)

mcp-config-vscode-ado:  ## Write .vscode/mcp.json for ADO
	@$(MAKE) mcp-config-vscode INTEGRATION=ado

mcp-config-vscode-jira: ## Write .vscode/mcp.json for Jira
	@$(MAKE) mcp-config-vscode INTEGRATION=jira

mcp-config-vscode-both: ## Write .vscode/mcp.json for both ADO and Jira
	@$(MAKE) mcp-config-vscode INTEGRATION=both

# ─── Webhook bridge ────────────────────────────────────────────────────────────
serve: ## Start webhook bridge locally (port 8080, auto-reload)
	qa-stlc-serve --host 0.0.0.0 --port 8080 --reload

serve-prod: ## Start webhook bridge (production mode, no reload)
	qa-stlc-serve --host 0.0.0.0 --port 8080

docker-build-webhook: ## Build webhook bridge Docker image
	docker build -f Dockerfile.webhook -t stlc-webhook-bridge:latest .

docker-run-webhook: ## Run webhook bridge in Docker (reads from .env)
	docker run --rm -p 8080:8080 \
	  --env-file .env \
	  -e PLAYWRIGHT_MCP_URL=http://host.docker.internal:8931/mcp \
	  stlc-webhook-bridge:latest

# ─── Hook registration ─────────────────────────────────────────────────────────
register-ado-hooks: ## Register ADO Service Hooks — requires BRIDGE_URL=https://...
	@test -n "$(BRIDGE_URL)" \
	  || (echo "Usage: make register-ado-hooks BRIDGE_URL=https://your-bridge" && exit 1)
	python scripts/register_ado_hooks.py --bridge-url $(BRIDGE_URL)

register-jira-hooks: ## Register Jira webhook — requires BRIDGE_URL=https://...
	@test -n "$(BRIDGE_URL)" \
	  || (echo "Usage: make register-jira-hooks BRIDGE_URL=https://your-bridge" && exit 1)
	python scripts/register_jira_hooks.py --bridge-url $(BRIDGE_URL)

register-hooks: ## Register both ADO and Jira hooks — requires BRIDGE_URL=https://...
	$(MAKE) register-ado-hooks  BRIDGE_URL=$(BRIDGE_URL)
	$(MAKE) register-jira-hooks BRIDGE_URL=$(BRIDGE_URL)

# ─── Azure Functions deploy ────────────────────────────────────────────────────
deploy-azure: ## Deploy webhook bridge to Azure Functions — requires FUNC_APP=<name>
	@test -n "$(FUNC_APP)" \
	  || (echo "Usage: make deploy-azure FUNC_APP=stlc-webhook-bridge" && exit 1)
	cd azure_functions && func azure functionapp publish $(FUNC_APP) --python

# ─── Migration helper targets ──────────────────────────────────────────────────
# Defaults: integration=both (every agent reachable), conflict=interactive.
# Override on the command line:
#   make migrate SOURCE=./old HELIX=./new INTEGRATION=ado CONFLICT=overwrite \
#                PRESERVE_TREE=1 FEATURES=vrt
#
# PRESERVE_TREE=1      → adds --preserve-tree (mirror source subfolder grouping)
# FEATURES=vrt         → adds --features=vrt (VRT also auto-detected from source)
CONFLICT       ?= interactive
PRESERVE_TREE  ?=
FEATURES       ?=

# Compose optional flags only when set, so older invocations still work.
_PRESERVE_FLAG = $(if $(PRESERVE_TREE),--preserve-tree)
_FEATURES_FLAG = $(if $(FEATURES),--features=$(FEATURES))

migrate-preview: ## Preview migration without writing files (SOURCE=<dir> HELIX=<dir>)
	@test -n "$(SOURCE)" \
	  || (echo "Usage: make migrate-preview SOURCE=./old-tests HELIX=./helix-qa" && exit 1)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make migrate-preview SOURCE=./old-tests HELIX=./helix-qa" && exit 1)
	$(VENV)/bin/stlc-migrate --source $(SOURCE) --helix $(HELIX) --dry-run \
	  $(_PRESERVE_FLAG) $(_FEATURES_FLAG)

migrate: ## Migrate a Playwright project (SOURCE=<dir> HELIX=<dir> [INTEGRATION=...] [CONFLICT=...] [PRESERVE_TREE=1] [FEATURES=vrt])
	@test -n "$(SOURCE)" \
	  || (echo "Usage: make migrate SOURCE=./old-tests HELIX=./helix-qa [INTEGRATION=both] [CONFLICT=overwrite] [PRESERVE_TREE=1] [FEATURES=vrt]" && exit 1)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make migrate SOURCE=./old-tests HELIX=./helix-qa [INTEGRATION=both] [CONFLICT=overwrite] [PRESERVE_TREE=1] [FEATURES=vrt]" && exit 1)
	@mkdir -p $(HELIX)
	$(VENV)/bin/stlc-migrate \
	  --source $(SOURCE) \
	  --helix $(HELIX) \
	  --integration $(INTEGRATION) \
	  --conflict $(CONFLICT) \
	  $(_PRESERVE_FLAG) $(_FEATURES_FLAG)
	@echo ""
	@echo "Next steps (in $(HELIX)):"
	@echo "  npm install                          # picks up dotenv + @types/* companions"
	@echo "  npx tsc --noEmit                     # should be clean"
	@echo "  npm test                             # healing fires on broken primary selectors"
	@echo "  npm run healix:dashboard             # http://localhost:7890 — Confirm/Revert UI"
	@echo "  npm run healix:review                # http://localhost:7891 — read-only mirror"
	@test -z "$(FEATURES)" || echo "  npm run vrt:baseline                 # VRT: capture baseline screenshots"
	@test -z "$(FEATURES)" || echo "  npm run vrt:test                     # VRT: compare against baselines"

migrate-ado:  ## Migrate with ADO skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=ado SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-jira: ## Migrate with Jira skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=jira SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-both: ## Migrate with all agent skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=both SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-help: ## Show stlc-migrate CLI help
	$(VENV)/bin/stlc-migrate --help

audit-migration: ## Verify a migrated tree is agent-ready (HELIX=<dir>)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make audit-migration HELIX=./helix-qa" && exit 1)
	@echo "=== Auditing $(HELIX) ==="
	@$(VENV)/bin/python -c "\
	from stlc_agents.agent_helix_writer.tools.helix_write import inspect_helix_project; \
	r = inspect_helix_project('$(HELIX)'); \
	print('framework_state:', r['framework_state']); \
	print('recommendation: ', r['recommendation']); \
	print('existing_infra: %d files' % len(r['existing_infra'])); \
	print('missing_infra:  ', r['missing_infra'] or 'none'); \
	"
	@echo ""
	@echo "--- Agent assets ---"
	@test -f $(HELIX)/.mcp.json                         && echo "✓ .mcp.json"                          || echo "✗ .mcp.json"
	@test -d $(HELIX)/.claude/skills                    && echo "✓ .claude/skills/"                    || echo "✗ .claude/skills/"
	@test -d $(HELIX)/.github/copilot-instructions      && echo "✓ .github/copilot-instructions/"      || echo "✗ .github/copilot-instructions/"
	@test -f $(HELIX)/AGENT-BEHAVIOR.md                 && echo "✓ AGENT-BEHAVIOR.md"                  || echo "✗ AGENT-BEHAVIOR.md"
	@test -f $(HELIX)/ORCHESTRATION_RULES.md            && echo "✓ ORCHESTRATION_RULES.md"             || echo "✗ ORCHESTRATION_RULES.md"
	@echo ""
	@echo "--- Healer scaffold ---"
	@for f in LocatorHealer.ts LocatorRepository.ts TimingHealer.ts VisualIntentChecker.ts HealingDashboard.ts dashboard-server.ts; do \
	  test -f $(HELIX)/src/utils/locators/$$f \
	    && echo "✓ src/utils/locators/$$f" \
	    || echo "✗ src/utils/locators/$$f"; \
	done
	@echo ""
	@echo "--- VRT scaffold (only when --features=vrt was used) ---"
	@if [ -d $(HELIX)/src/helper/vrt ]; then \
	  for f in vrtCapture.util.ts vrtReport.util.ts; do \
	    test -f $(HELIX)/src/helper/vrt/$$f \
	      && echo "✓ src/helper/vrt/$$f" \
	      || echo "✗ src/helper/vrt/$$f"; \
	  done; \
	  test -f $(HELIX)/src/test/steps/vrt.steps.ts \
	    && echo "✓ src/test/steps/vrt.steps.ts" \
	    || echo "✗ src/test/steps/vrt.steps.ts"; \
	else \
	  echo "  (VRT not scaffolded — pass FEATURES=vrt to make migrate to enable)"; \
	fi
	@echo ""
	@echo "--- Migration report ---"
	@test -f $(HELIX)/MIGRATION-REPORT.md && echo "✓ MIGRATION-REPORT.md" || echo "✗ MIGRATION-REPORT.md"
	@echo ""
	@echo "--- Heal store / log (if tests have run) ---"
	@ls $(HELIX)/self-heals/*.json 2>/dev/null | head -3 || echo "  (no heal-store yet — run tests to populate)"
	@test -f $(HELIX)/self-heals/heal.log && echo "✓ self-heals/heal.log" || echo "  (no heal log yet)"

# ─── Tests ─────────────────────────────────────────────────────────────────────
test: test-all ## Alias for test-all

test-webhook: ## Run webhook unit tests only
	$(PYTEST) tests/test_webhook.py -v

test-all: ## Run all tests
	$(PYTEST) tests/ -v

# ─── Publish ───────────────────────────────────────────────────────────────────
# Bump version in package.json + pyproject.toml before running.
publish: ## Publish to npm and PyPI (bump version first)
	@test -x $(VENV)/bin/pip || { echo "Bootstrapping $(VENV)…"; $(PYTHON) -m venv $(VENV) && $(PIP) install --upgrade --quiet pip; }
	npm publish --access public
	$(PIP) install --quiet build twine
	rm -rf dist
	$(VENV)/bin/python -m build
	$(VENV)/bin/python -m twine upload --skip-existing dist/*

# ─── Clean ─────────────────────────────────────────────────────────────────────
clean: ## Remove venv, build artefacts, and __pycache__
	rm -rf $(VENV) __pycache__ dist *.egg-info
	find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
	find . -type f -name "*.pyc" -delete
	@echo "✓ Cleaned"	