PYTHON ?= python
DVC ?= dvc
DVC_SITE_CACHE_DIR ?= $(CURDIR)/.dvc-cache
DVC_CMD = DVC_SITE_CACHE_DIR=$(DVC_SITE_CACHE_DIR) $(DVC)

# === Session 2 MLOps — Teaching-Oriented Makefile ===
# Targets grouped by demonstration phase for easy teaching
# ========================================================

.PHONY: help \
        install mlflow-server \
        init-dvc validate repro repro-offline \
        graph metrics inspect \
        test check \
        demo demo-step demo-status \
        leak-demo prepare-demo validate-demo pipeline-demo repro-demo fail-demo \
        01-leakage 02-split 03-validation 04-dvc-pipeline 05-recomputation 06-proof-linking 07-early-failure
#

# === General targets ===

help: ## Show this help message
	@echo "Session 2 MLOps — Available targets:"
	@echo ""
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | while read -r line; do \
		target=$$(echo "$$line" | awk -F: '{print $$1}' | tr -d ' '); \
		descr=$$(echo "$$line" | awk -F'## ' '{print $$2}'); \
		printf "  %-22s %s\n" "$$target" "$$descr"; \
	done

install: ## Install Python dependencies
	$(PYTHON) -m pip install -r requirements.txt

mlflow-server: ## Start MLflow tracking server (use in separate terminal)
	$(PYTHON) -m mlflow server --backend-store-uri sqlite:///mlflow.db --host 127.0.0.1 --port 5000

init-dvc: ## Initialize DVC and add raw data
	test -d .dvc || $(DVC_CMD) init --no-scm
	test -f data/raw/customers.csv.dvc || $(DVC_CMD) add data/raw/customers.csv

# === DVC pipeline execution ===

repro: init-dvc ## Run DVC pipeline (uses MLflow URI from params.yaml)
	$(DVC_CMD) repro

repro-offline: init-dvc ## Run DVC pipeline with local SQLite MLflow tracking
	MLFLOW_TRACKING_URI=sqlite:///mlflow-offline.db MLFLOW_EXPERIMENT_NAME=mlops-course-session-2-offline $(DVC_CMD) repro

graph: init-dvc ## Show the DVC DAG (dependency graph)
	$(DVC_CMD) dag

metrics: ## Show tracked metrics from DVC
	$(DVC_CMD) metrics show

inspect: ## Pretty-print the final run manifest
	$(PYTHON) -m json.tool reports/run_manifest.json

status: ## Show DVC pipeline status
	$(DVC_CMD) status

# === Testing ===

test: ## Run unit tests for validation logic
	$(PYTHON) -m pytest

check: repro-offline test ## Full validation: run pipeline and tests offline

validate: ## Run data contract validation
	$(PYTHON) src/validate_data.py

# === Teaching demonstration targets ===
# These targets guide the teacher through each concept step by step

demo: ## Run the complete teacher demonstration script (interactive, 6 steps)
	$(PYTHON) demo.py

demo-step: ## Run a single demo step (specify STEP=1..6, e.g., make demo-step STEP=3)
	$(PYTHON) demo.py $(STEP)

demo-status: ## Quick status check for teaching context
	@echo "=== Teaching Context ==="
	@echo "1. DVC Status:"
	@$(DVC_CMD) status 2>/dev/null || echo "  (DVC not initialized)"
	@echo ""
	@echo "2. Pipeline DAG:"
	@$(DVC_CMD) dag 2>/dev/null || echo "  (Pipeline not yet run)"
	@echo ""
	@echo "3. Metrics:"
	@$(DVC_CMD) metrics show 2>/dev/null || echo "  (No metrics yet)"
	@echo ""
	@echo "4. Manifest:"
	@test -f reports/run_manifest.json && echo "  ✓ Manifest exists" || echo "  (Not yet created)"

# === Individual demonstration steps (use teaching-steps/) ===

leak-demo: ## Step 1: Show data leakage comparison
	@echo "=== Step 1: Data Leakage ==="
	@$(PYTHON) src/compare_protocols.py

prepare-demo: ## Step 2: Show modular prepare.py stage
	@echo "=== Step 2: Pipeline Modularization ==="
	@echo "Showing the 4 stages: validate -> prepare -> train -> evaluate"
	@echo ""
	@echo "1. validate_data.py - data contract check"
	@cat src/validate_data.py | head -15
	@echo "... (truncated)"
	@echo ""
	@echo "2. prepare.py - train/test split after validation"
	@cat src/prepare.py | head -15
	@echo "... (truncated)"
	@echo ""
	@echo "3. train.py - model training on train split only"
	@cat src/train.py | head -15
	@echo "... (truncated)"
	@echo ""
	@echo "4. evaluate.py - metrics + MLflow logging + manifest"
	@cat src/evaluate.py | head -15
	@echo "... (truncated)"

validate-demo: ## Step 3: Data contract validation demonstration
	@echo "=== Step 3: Data Contract Validation ==="
	@mkdir -p reports
	@$(PYTHON) src/validate_data.py
	@echo ""
	@echo "Validation report:"
	@cat reports/data_validation.json | $(PYTHON) -m json.tool

pipeline-demo: ## Step 4: DVC pipeline declaration and initialization
	@echo "=== Step 4: DVC Pipeline ==="
	@echo "Pipeline definition:"
	@cat dvc.yaml

repro-demo: ## Step 5: Selective recomputation demonstration
	@echo "=== Step 5: Selective Recomputation ==="
	@echo "Current DVC status:"
	@$(DVC_CMD) status 2>/dev/null || echo "Run 'make init-dvc' first"
	@echo ""
	@echo "Run 'make repro-offline' to see what gets executed"

fail-demo: ## Step 6: Early failure detection demonstration
	@echo "=== Step 6: Early Failure Detection ==="
	@echo "Validation acts as a quality gate. If data is invalid:"
	@echo "  - validate_data.py exits with code 1"
	@echo "  - DVC pipeline stops before prepare stage"
	@echo ""
	@echo "Run 'make validate' to see current validation status"

# === Teaching steps with own code (teaching-steps/) ===

01-leakage: ## Step 1: Data Leakage (teaching-steps)
	@echo "=== Step 1: Data Leakage ==="
	@$(PYTHON) src/compare_protocols.py

02-split: ## Step 2: Data Splitting (teaching-steps)
	@echo "=== Step 2: Data Splitting ==="
	@$(MAKE) validate
	@$(MAKE) prepare

03-validation: ## Step 3: Data Validation (teaching-steps)
	@echo "=== Step 3: Data Validation ==="
	@$(PYTHON) src/validate_data.py

04-dvc-pipeline: ## Step 4: DVC Pipeline Declaration (teaching-steps)
	@echo "=== Step 4: DVC Pipeline Declaration ==="
	@echo "Pipeline definition:"
	@cat dvc.yaml

05-recomputation: ## Step 5: Selective Recomputation (teaching-steps)
	@echo "=== Step 5: Selective Recomputation ==="
	@echo "DVC pipeline with selective recomputation"

06-proof-linking: ## Step 6: Proof Linking (teaching-steps)
	@echo "=== Step 6: Proof Linking ==="
	@echo "Manifest demonstration"

07-early-failure: ## Step 7: Early Failure Detection (teaching-steps)
	@echo "=== Step 7: Early Failure Detection ==="
	@echo "Validation gate demonstration"
