SHELL := /bin/bash

# --- Configuration ---
# USE_LOCAL: Controls whether to use local API keys or GitHub SSO cloud authentication
# - 'yes' (default): Uses --local flag, requires API keys in environment or ~/.pdd/api-env
# - 'no': Uses cloud mode, requires GitHub authentication via browser
#
# To override: make USE_LOCAL=no template
USE_LOCAL ?= yes

# USE_FORCE: Skip all interactive prompts (useful for automation/CI)
# - 'yes': Adds --force flag, skips file overwrite prompts and API key requests
# - 'no' (default): Interactive mode, will prompt when needed
#
# To override: make USE_FORCE=yes sync_all
# Recommended for sync operations to avoid constant file overwrite prompts
USE_FORCE ?= yes

# COMMAND_PREFIX: Optional command prefix for injecting environment variables.
# Example: COMMAND_PREFIX="env OPENAI_API_KEY=..."
#
COMMAND_PREFIX ?=

# Define the base command
PDD_CMD := pdd

# Build flags based on configuration
PDD_FLAGS :=
ifeq ($(USE_LOCAL),yes)
    PDD_FLAGS += --local
endif
ifeq ($(USE_FORCE),yes)
    PDD_FLAGS += --force
endif

# The final command wrapper
PDD := $(COMMAND_PREFIX) $(PDD_CMD) $(PDD_FLAGS)

# Directories to clean (generated by PDD)
GENERATED_DIRS := src/edit_file_tool src/examples src/tests

.PHONY: clean template help prompts prompt-info sync sync_all test

# --- Targets ---

# 1. Template Target
# Runs the PDD architecture template.
#
# Variable Mapping based on PDD Template Docs:
#   APP_NAME        (Optional) -> Context name for the app
#   PRD_FILE        (Required) -> Your primary spec (README.md)
#   TECH_STACK_FILE (Optional) -> Tech details (mapped to README.md for now)
#   DOC_FILES       (Optional) -> List of extra docs (e.g. UX, API specs)
#   INCLUDE_FILES   (Optional) -> List of source code to analyze
template:
	@echo "Generating architecture from EDIT_FILE_TOOL_README.md..."
	$(PDD) generate --template architecture/architecture_json \
		-e APP_NAME=edit-file-tool \
		-e PRD_FILE=EDIT_FILE_TOOL_README.md \
		-e TECH_STACK_FILE=EDIT_FILE_TOOL_README.md \
		--output architecture.json
		# Future usage (uncomment when you have these files):
		# -e DOC_FILES=docs/ux.md,docs/api.md \
		# -e INCLUDE_FILES=src/main.py,src/utils.py \

	@echo "Success! Open 'architecture_diagram.html' to verify your system design."

# 2. Clean Target
clean:
	@echo "Cleaning generated artifacts..."
	@rm -rf $(GENERATED_DIRS)
	@rm -f architecture.json architecture_diagram.html
	@rm -rf prompts/
	@echo "Clean complete."

# 3. Help / Debug Target
# View details about the specific template you are using
info:
	@$(PDD) templates show architecture/architecture_json

# --- Prompt Generation Targets ---
# Generate prompt templates dynamically based on architecture.json
# These targets work with ANY architecture - no hardcoded module names!

# 4. Generate all prompts from architecture.json
# This target:
#   1. Reads architecture.json to discover all modules
#   2. For each module, extracts MODULE name and LAYER
#   3. Runs 'pdd generate --template generic/generate_prompt' for each
#   4. Outputs .prompt files to prompts/ directory
prompts:
	@echo "Reading architecture.json to generate prompts..."
	@if [ ! -f architecture.json ]; then \
		echo "Error: architecture.json not found. Run 'make template' first."; \
		exit 1; \
	fi
	@echo "Generating prompts for all modules..."
	@python3 -c 'import json; arch = json.load(open("architecture.json")); [print(m["filename"].replace("_Python.prompt", "") + "|" + m["tags"][0] + "|" + m["filename"]) for m in arch]' \
	| while IFS='|' read MODULE LAYER OUTPUT; do \
		echo ""; \
		echo "==> Generating prompt for $$MODULE (layer: $$LAYER)..."; \
		$(PDD) generate --template generic/generate_prompt \
			-e MODULE=$$MODULE \
			-e LANG_OR_FRAMEWORK=Python \
			-e LAYER=$$LAYER \
			-e ARCHITECTURE_FILE=architecture.json \
			-e PRD_FILE=EDIT_FILE_TOOL_README.md \
			--output "prompts/$$OUTPUT" || exit 1; \
	done
	@echo ""
	@echo "All prompts generated successfully!"
	@echo "Prompt files are in the prompts/ directory"

# 5. View prompt template info
prompt-info:
	@$(PDD) templates show generic/generate_prompt

# --- Sync Targets ---
# Synchronize prompts with code and tests dynamically based on architecture.json
# These targets work with ANY architecture - no hardcoded module names!

# 6. Sync a specific module by name
# Usage: make sync MODULE=<module_name>
# Example: make sync MODULE=cli
# The module name should match the base name from architecture.json (without _Python.prompt suffix)
#
# Non-executable formats (TOML, YAML, JSON, XML, Markdown, Prisma, etc.) use 'pdd generate' instead of 'pdd sync'
# Format detection: Finds the prompt file in prompts/ and checks its suffix to determine format type
sync:
ifndef MODULE
	@echo "Error: MODULE parameter required. Usage: make sync MODULE=<module_name>"
	@echo "Example: make sync MODULE=cli"
	@exit 1
endif
	@echo "Processing module: $(MODULE)..."
	@# Find the prompt file for this module
	@PROMPT_FILE=$$(find prompts -name "$(MODULE)*" -type f | head -n 1); \
	if [ -z "$$PROMPT_FILE" ]; then \
		echo "Error: Prompt file not found for module $(MODULE) in prompts/"; \
		exit 1; \
	fi; \
	echo "  → Found prompt: $$PROMPT_FILE"; \
	BASENAME=$$(basename "$$PROMPT_FILE" .prompt); \
	if echo "$$BASENAME" | grep -qE '_(TOML|YAML|yml|JSON|JSONL|XML|INI|CSV|Markdown|md|LaTeX|tex|rst|txt|log|Prisma|prompt|Makefile)$$'; then \
		echo "  → Detected non-executable format - using 'pdd generate' (no tests)"; \
		echo "  → Command: $(PDD) generate $$PROMPT_FILE"; \
		$(PDD) generate "$$PROMPT_FILE" < /dev/null; \
	else \
		echo "  → Detected executable code - using 'pdd sync' (with tests)"; \
		echo "  → Command: $(PDD) sync $(MODULE)"; \
		$(PDD) sync $(MODULE) < /dev/null; \
	fi

# 7. Sync all modules in priority order (dynamically reads architecture.json)
# This target:
#   1. Reads architecture.json to discover all modules
#   2. Sorts them by priority (1 -> N) to respect dependencies
#   3. Detects format type from prompt filename suffix
#   4. Runs 'pdd sync <module>' for executable code OR 'pdd generate' for non-executable formats
#
# Non-executable formats (TOML, YAML, JSON, XML, Markdown, Prisma, etc.) are automatically detected
# by checking the prompt filename suffix and use 'pdd generate' instead of 'pdd sync' (no tests generated)
sync_all:
	@echo "Reading architecture.json to determine sync order..."
	@if [ ! -f architecture.json ]; then \
		echo "Error: architecture.json not found. Run 'make template' first."; \
		exit 1; \
	fi
	@echo "Syncing all modules in priority order..."
	@python3 -c 'import json; arch = json.load(open("architecture.json")); modules = sorted(arch, key=lambda m: m["priority"]); [print(m["filename"] + "|" + str(m["priority"])) for m in modules]' \
	| while IFS='|' read filename priority; do \
		echo ""; \
		basename=$$(echo "$$filename" | sed 's/\.prompt$$//'); \
		echo "==> Processing $$basename (priority $$priority)..."; \
		PROMPT_FILE="prompts/$$filename"; \
		if [ ! -f "$$PROMPT_FILE" ]; then \
			echo "Error: Prompt file not found: $$PROMPT_FILE"; \
			exit 1; \
		fi; \
		echo "    → Found prompt: $$PROMPT_FILE"; \
		if echo "$$basename" | grep -qE '_(TOML|YAML|yml|JSON|JSONL|XML|INI|CSV|Markdown|md|LaTeX|tex|rst|txt|log|Prisma|prompt|Makefile)$$'; then \
			echo "    → Detected non-executable format - using 'pdd generate' (no tests)"; \
			echo "    → Command: $(PDD) generate $$PROMPT_FILE"; \
			$(PDD) generate "$$PROMPT_FILE" < /dev/null || exit 1; \
		else \
			echo "    → Detected executable code - using 'pdd sync' (with tests)"; \
			module=$$(echo "$$basename" | sed 's/_Python$$//' | sed 's/_TypeScript$$//' | sed 's/_JavaScript$$//' | sed 's/_Java$$//' | sed 's/_Go$$//' | sed 's/_Rust$$//' | sed 's/_cpp$$//'); \
			echo "    → Command: $(PDD) sync $$module"; \
			$(PDD) sync $$module < /dev/null || exit 1; \
		fi; \
	done
	@echo ""
	@echo "All modules synchronized successfully!"
	@echo "Code, tests, and coverage reports are in their respective directories"

# 8. Test Target
# Runs pytest using configuration from pyproject.toml
# The pyproject.toml configures:
#   - testpaths = ["src/tests"]
#   - pythonpath = ["src"]
#   - asyncio_mode = "auto"
test:
	@echo "Running pytest (using pyproject.toml config)..."
	pytest -vv
