# ============================================================
#  project-packer Makefile
#  Author: Udaya Raj Joshi
# ============================================================

# --- Version management ---
CURRENT_VERSION := $(shell grep -oP 'version="\K[^"]+' setup.py | head -1)

# --- Project settings ---
PROJECT_NAME    := project-packer
PACKER          := python3 packer.py
PACKED_FILE     := $(PROJECT_NAME)-$(CURRENT_VERSION).py
BACKUP_DIR      := ./backups
TIMESTAMP       := $(shell date +%Y%m%d_%H%M%S)
BACKUP_FILE     := $(BACKUP_DIR)/$(PROJECT_NAME)_backup_$(TIMESTAMP).tar.xz

# --- Python / virtual environment ---
PYTHON          := python3
PIP             := pip3
VENV_DIR        := venv
VENV_PYTHON     := $(VENV_DIR)/bin/python
VENV_PIP        := $(VENV_DIR)/bin/pip

# --- Colors ---
RED    := \033[0;31m
GREEN  := \033[0;32m
YELLOW := \033[0;33m
BLUE   := \033[0;34m
CYAN   := \033[0;36m
NC     := \033[0m

# ============================================================
#  DEFAULT
# ============================================================
.PHONY: help
help:
	@echo "$(GREEN)project-packer$(NC) v$(CURRENT_VERSION)"
	@echo ""
	@echo "$(CYAN)PACK / UNPACK$(NC)"
	@echo "  $(BLUE)pack$(NC)         - Pack this project into a single .py file"
	@echo "  $(BLUE)unpack$(NC)       - Unpack a packed file  (make unpack F=file.py)"
	@echo ""
	@echo "$(CYAN)TESTING$(NC)"
	@echo "  $(BLUE)test$(NC)         - Round-trip: pack → unpack → diff"
	@echo "  $(BLUE)syntax$(NC)       - Quick syntax check"
	@echo "  $(BLUE)run$(NC)          - Show packer CLI help"
	@echo ""
	@echo "$(CYAN)DEVELOPMENT$(NC)"
	@echo "  $(BLUE)venv$(NC)         - Create a virtual environment"
	@echo "  $(BLUE)install$(NC)      - Install packer into the venv (editable)"
	@echo "  $(BLUE)uninstall$(NC)    - Remove packer from the venv"
	@echo ""
	@echo "$(CYAN)BUILD / CLEANUP$(NC)"
	@echo "  $(BLUE)clean$(NC)        - Remove caches and build artifacts"
	@echo "  $(BLUE)distclean$(NC)    - clean + remove venv and packed files"
	@echo "  $(BLUE)dist$(NC)         - Build sdist + wheel into ./dist/"
	@echo ""
	@echo "$(CYAN)RELEASE$(NC)"
	@echo "  $(BLUE)backup$(NC)       - Timestamped tarball of the project"
	@echo "  $(BLUE)release$(NC)      - Bump version, commit, tag, push"
	@echo ""
	@echo "$(CYAN)SHORTCUTS$(NC)"
	@echo "  $(BLUE)all$(NC)          - clean + pack + test"
	@echo ""

# ============================================================
#  PACK / UNPACK
# ============================================================
.PHONY: pack
pack:
	@echo "$(BLUE)Packing project...$(NC)"
	$(PACKER) pack . --manifest MANIFEST.in -v
	@echo "$(GREEN)✓ Packed → $(PACKED_FILE)$(NC)"

.PHONY: unpack
unpack:
	@if [ -z "$(F)" ]; then \
		echo "$(RED)Usage: make unpack F=<packed_file>$(NC)"; \
		exit 1; \
	fi
	@echo "$(BLUE)Unpacking $(F)...$(NC)"
	$(PACKER) unpack "$(F)" -v

# ============================================================
#  TESTING
# ============================================================
.PHONY: test
test:
	@echo "$(BLUE)Running pack/unpack round-trip test...$(NC)"
	@rm -rf /tmp/packer-test && mkdir -p /tmp/packer-test
	@$(PACKER) pack . -o /tmp/packer-test/test.py > /dev/null
	@$(PACKER) unpack /tmp/packer-test/test.py /tmp/packer-test/unpacked > /dev/null
	@fail=0; \
	for f in packer.py setup.py Makefile; do \
		if ! diff -q "$$f" "/tmp/packer-test/unpacked/$$f" > /dev/null 2>&1; then \
			echo "$(RED)✗ Mismatch: $$f$(NC)"; \
			diff "$$f" "/tmp/packer-test/unpacked/$$f" | head -10; \
			fail=1; \
		fi; \
	done; \
	if [ $$fail -eq 0 ]; then \
		echo "$(GREEN)✓ Round-trip OK$(NC)"; \
	fi; \
	rm -rf /tmp/packer-test; \
	exit $$fail

.PHONY: syntax
syntax:
	@echo "$(BLUE)Checking syntax...$(NC)"
	@$(PYTHON) -m py_compile packer.py setup.py && echo "$(GREEN)✓ Syntax OK$(NC)"
	@$(PYTHON) -c "import ast; ast.parse(open('packer.py').read())" && echo "$(GREEN)✓ AST OK$(NC)"

.PHONY: run
run:
	@$(PACKER) --help

# ============================================================
#  DEVELOPMENT (venv + local install)
# ============================================================
.PHONY: venv
venv:
	@if [ ! -d "$(VENV_DIR)" ]; then \
		echo "$(BLUE)Creating venv...$(NC)"; \
		$(PYTHON) -m venv $(VENV_DIR); \
		echo "$(GREEN)✓ venv created at $(VENV_DIR)$(NC)"; \
	else \
		echo "$(YELLOW)venv already exists$(NC)"; \
	fi

.PHONY: install
install: venv
	@echo "$(BLUE)Installing $(PROJECT_NAME) in editable mode...$(NC)"
	$(VENV_PIP) install --upgrade pip
	$(VENV_PIP) install -e .
	@echo "$(GREEN)✓ Installed. Run: $(VENV_DIR)/bin/packer --help$(NC)"

.PHONY: uninstall
uninstall:
	@if [ -d "$(VENV_DIR)" ]; then \
		echo "$(BLUE)Uninstalling from venv...$(NC)"; \
		$(VENV_PIP) uninstall -y $(PROJECT_NAME); \
		echo "$(GREEN)✓ Uninstalled$(NC)"; \
	else \
		echo "$(YELLOW)No venv to uninstall from$(NC)"; \
	fi

# ============================================================
#  CLEAN
# ============================================================
.PHONY: clean
clean:
	@echo "$(BLUE)Removing caches and build artifacts...$(NC)"
	@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
	@find . -type f -name "*.pyc" -delete
	@find . -type f -name "*.pyo" -delete
	@find . -type f -name "*.so" -delete
	@rm -rf build/ dist/ *.egg-info/ .pytest_cache/ .coverage htmlcov/
	@rm -rf /tmp/packer-test
	@echo "$(GREEN)✓ Clean complete$(NC)"

.PHONY: distclean
distclean: clean
	@echo "$(BLUE)Removing venv and packed files...$(NC)"
	@rm -rf $(VENV_DIR)
	@rm -f $(PROJECT_NAME)-*.py
	@rm -rf $(PROJECT_NAME)-*_unpacked/
	@echo "$(GREEN)✓ Distclean complete$(NC)"

# ============================================================
#  DIST (local build — no upload)
# ============================================================
.PHONY: dist
dist: clean
	@echo "$(BLUE)Building sdist + wheel...$(NC)"
	@$(PIP) install --quiet --upgrade build
	@$(PYTHON) -m build
	@echo "$(GREEN)✓ Built in ./dist/$(NC)"
	@ls -lh dist/

# ============================================================
#  BACKUP
# ============================================================
.PHONY: backup
backup: $(BACKUP_DIR)
	@echo "$(BLUE)Creating backup...$(NC)"
	@tar -cJf $(BACKUP_FILE) \
		--exclude='__pycache__' \
		--exclude='*.pyc' \
		--exclude='venv' \
		--exclude='.git' \
		--exclude='build' \
		--exclude='dist' \
		--exclude='*.egg-info' \
		--exclude='backups' \
		.
	@echo "$(GREEN)✓ Backup: $(BACKUP_FILE)$(NC)"

$(BACKUP_DIR):
	@mkdir -p $(BACKUP_DIR)

# ============================================================
#  RELEASE (git only)
# ============================================================
.PHONY: release
release:
	@echo "$(GREEN)Current version: $(CURRENT_VERSION)$(NC)"
	@read -p "New version (or Enter to keep $(CURRENT_VERSION)): " VERSION; \
	if [ -z "$$VERSION" ]; then VERSION=$(CURRENT_VERSION); fi; \
	echo "$(BLUE)Setting version to $$VERSION...$(NC)"; \
	sed -i 's/version="[^"]*"/version="'"$$VERSION"'"/' setup.py; \
	git add setup.py; \
	git commit -m "chore: bump version to $$VERSION" || true; \
	git tag -a "v$$VERSION" -m "Release v$$VERSION"; \
	git push; \
	git push origin "v$$VERSION"; \
	echo "$(GREEN)✓ Released v$$VERSION$(NC)"; \
	echo "$(YELLOW)Create the GitHub release:$(NC)"; \
	echo "  https://github.com/blee-design/project-packer/releases/new?tag=v$$VERSION"

# ============================================================
#  SHORTCUTS
# ============================================================
.PHONY: all
all: clean pack test
