# Context42 - Justfile for release automation
# Usage: just <recipe>
# Documentation: https://just.systems

# =============================================================================
# Configuration
# =============================================================================

set shell := ["bash", "-c"]
set dotenv-load := true

# =============================================================================
# Default Recipe
# =============================================================================

# Show available recipes
default:
    @just --list

# =============================================================================
# Helper Recipes (Internal)
# =============================================================================
# Note: Recipes prefixed with _ are not shown in `just --list`

# Check if command exists
_require cmd:
    @command -v {{cmd}} >/dev/null || (echo "❌ Error: {{cmd}} not found. Please install it first."; exit 1)

# Check if environment variable is set
_require-env var:
    #!/usr/bin/env bash
    set -euo pipefail

    if [ -z "${!{{var}}:-}" ]; then
        echo "❌ Error: {{var}} environment variable not set"
        exit 1
    fi

# =============================================================================
# Version Management
# =============================================================================

# Show current version
version:
    @grep -Po '(?<=__version__ = ")[^"]+' src/context42/__init__.py

# Bump version to specified semver (e.g., just bump 0.4.1)
# Parameters:
#   VERSION: Semver version string (MAJOR.MINOR.PATCH)
bump VERSION:
    #!/usr/bin/env bash
    set -euo pipefail

    # Validate semver format
    if ! echo "{{VERSION}}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
        echo "❌ Error: Invalid version format '{{VERSION}}'"
        echo "   Expected format: MAJOR.MINOR.PATCH (e.g., 0.4.1)"
        exit 1
    fi

    echo "📦 Bumping version to {{VERSION}}..."

    # Update __init__.py (macOS/Linux compatible)
    sed -i.bak 's/__version__ = "[^"]*"/__version__ = "{{VERSION}}"/' src/context42/__init__.py
    rm src/context42/__init__.py.bak

    # Update pyproject.toml (macOS/Linux compatible)
    sed -i.bak 's/^version = "[^"]*"/version = "{{VERSION}}"/' pyproject.toml
    rm pyproject.toml.bak

    echo "✅ Version updated to {{VERSION}}"
    echo ""
    echo "Files modified:"
    echo "  - src/context42/__init__.py"
    echo "  - pyproject.toml"
    echo ""
    echo "Next steps:"
    echo "  1. Update CHANGELOG.md"
    echo "  2. git add -A && git commit -m 'Bump version to {{VERSION}}'"
    echo "  3. just release {{VERSION}}"

# =============================================================================
# Build
# =============================================================================

# Clean build artifacts and cache files
clean:
    #!/usr/bin/env bash
    set -euo pipefail

    echo "🧹 Cleaning build artifacts..."

    # Remove build directories
    rm -rf dist/ build/ *.egg-info src/*.egg-info

    # Remove Python cache files
    find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
    find . -type f -name "*.pyc" -delete 2>/dev/null || true
    find . -type f -name "*.pyo" -delete 2>/dev/null || true

    echo "✅ Cleaned build artifacts"

# Build Python package (wheel and sdist)
# Automatically cleans artifacts before building
build: clean
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "📦 Building package..."
    python -m build
    
    echo ""
    echo "✅ Build complete:"
    ls -lh dist/

# =============================================================================
# Git Operations
# =============================================================================

# Push current branch to remote origin
# Automatically detects current branch (master, main, etc.)
# Usage: just push
push:
    #!/usr/bin/env bash
    set -euo pipefail

    BRANCH=$(git branch --show-current)

    if [ -z "$BRANCH" ]; then
        echo "❌ Error: Not on any branch (detached HEAD?)"
        exit 1
    fi

    echo "📤 Pushing branch '$BRANCH' to origin..."
    git push origin "$BRANCH"

    echo "✅ Branch '$BRANCH' pushed to origin"

# =============================================================================
# PyPI Publishing
# =============================================================================

# Upload package to TestPyPI for testing
# Requires: twine
# Usage: just publish-test
publish-test: build (_require "twine")
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "🧪 Uploading to TestPyPI..."
    twine upload --repository testpypi dist/*
    
    echo ""
    echo "✅ Uploaded to TestPyPI"
    echo ""
    echo "Test installation:"
    echo "  pip install --index-url https://test.pypi.org/simple/ context42-io"

# Upload package to PyPI (production release)
# Requires: twine, PyPI credentials configured
# Usage: just publish
publish: build (_require "twine")
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "🚀 Uploading to PyPI..."
    twine upload dist/*
    
    echo ""
    echo "✅ Published to PyPI"
    echo ""
    echo "Install with:"
    echo "  pip install context42-io"

# =============================================================================
# Git Tagging
# =============================================================================

# Create annotated git tag for release
# Parameters:
#   VERSION: Version number (must match code version)
# Usage: just tag 0.4.1
tag VERSION:
    #!/usr/bin/env bash
    set -euo pipefail
    
    # Verify version matches code
    CODE_VERSION=$(grep -Po '(?<=__version__ = ")[^"]+' src/context42/__init__.py)
    
    if [ "$CODE_VERSION" != "{{VERSION}}" ]; then
        echo "❌ Error: Code version ($CODE_VERSION) doesn't match tag version ({{VERSION}})"
        echo "   Run: just bump {{VERSION}}"
        exit 1
    fi
    
    # Check for uncommitted changes
    if ! git diff-index --quiet HEAD --; then
        echo "❌ Error: Uncommitted changes. Commit first."
        exit 1
    fi
    
    echo "🏷️  Creating tag v{{VERSION}}..."
    git tag -a "v{{VERSION}}" -m "Release v{{VERSION}}"
    
    echo "✅ Tag v{{VERSION}} created"
    echo ""
    echo "Push with:"
    echo "  git push origin v{{VERSION}}"

# Push git tag to remote origin
# Parameters:
#   VERSION: Version number (tag must exist locally)
# Usage: just push-tag 0.4.1
push-tag VERSION:
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "📤 Pushing tag v{{VERSION}} to origin..."
    git push origin "v{{VERSION}}"
    
    echo "✅ Tag pushed"
    echo ""
    echo "GitHub release URL:"
    echo "  https://github.com/context42-io/context42/releases/new?tag=v{{VERSION}}"

# =============================================================================
# Full Release Workflow
# =============================================================================

# Execute complete release workflow
# Creates tag, builds package, publishes to PyPI, and pushes tag
# Parameters:
#   VERSION: Version number to release
# Requires: All pre-flight checks to pass
# Usage: just release 0.4.1
release VERSION:
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "🚀 Starting release v{{VERSION}}..."
    echo ""
    
    # Verify version
    CODE_VERSION=$(grep -Po '(?<=__version__ = ")[^"]+' src/context42/__init__.py)
    TOML_VERSION=$(grep -Po '(?<=^version = ")[^"]+' pyproject.toml)
    
    if [ "$CODE_VERSION" != "{{VERSION}}" ]; then
        echo "❌ Error: __init__.py version ($CODE_VERSION) doesn't match {{VERSION}}"
        exit 1
    fi
    
    if [ "$TOML_VERSION" != "{{VERSION}}" ]; then
        echo "❌ Error: pyproject.toml version ($TOML_VERSION) doesn't match {{VERSION}}"
        exit 1
    fi
    
    # Check CHANGELOG
    if ! grep -q "## \[{{VERSION}}\]" CHANGELOG.md; then
        echo "❌ Error: CHANGELOG.md doesn't have entry for {{VERSION}}"
        exit 1
    fi
    
    # Check for uncommitted changes
    if ! git diff-index --quiet HEAD --; then
        echo "❌ Error: Uncommitted changes. Commit first."
        exit 1
    fi
    
    echo "✅ Pre-flight checks passed"
    echo ""
    
    # Create tag
    just tag {{VERSION}}
    
    # Build and publish
    just publish
    
    # Push tag
    just push-tag {{VERSION}}
    
    echo ""
    echo "🎉 Release v{{VERSION}} complete!"
    echo ""
    echo "Next steps:"
    echo "  1. Create GitHub release at:"
    echo "     https://github.com/context42-io/context42/releases/new?tag=v{{VERSION}}"
    echo "  2. Copy CHANGELOG entry to release notes"

# =============================================================================
# Development Helpers
# =============================================================================

# Install package in development mode with dev dependencies
# Usage: just dev
dev:
    pip install -e ".[dev]"

# Run test suite
# Usage: just test
# Note: Tests not yet implemented
test:
    @echo "⚠️  No tests configured yet"
    # pytest tests/

# Check code style and formatting with ruff
# Requires: ruff
# Usage: just lint
lint: (_require "ruff")
    ruff check src/
    ruff format --check src/

# Format code with ruff
# Requires: ruff
# Usage: just fmt
fmt: (_require "ruff")
    ruff format src/

# =============================================================================
# Pre-release Checklist
# =============================================================================

# Run pre-flight checks before release
# Verifies version consistency, CHANGELOG entry, and git status
# Parameters:
#   VERSION: Version number to verify
# Usage: just preflight 0.4.1
preflight VERSION:
    #!/usr/bin/env bash
    set -euo pipefail
    
    echo "🔍 Pre-flight check for v{{VERSION}}..."
    echo ""
    
    ERRORS=0
    
    # Check versions match
    CODE_VERSION=$(grep -Po '(?<=__version__ = ")[^"]+' src/context42/__init__.py)
    TOML_VERSION=$(grep -Po '(?<=^version = ")[^"]+' pyproject.toml)
    
    if [ "$CODE_VERSION" = "{{VERSION}}" ]; then
        echo "✅ __init__.py version: $CODE_VERSION"
    else
        echo "❌ __init__.py version: $CODE_VERSION (expected {{VERSION}})"
        ERRORS=$((ERRORS + 1))
    fi
    
    if [ "$TOML_VERSION" = "{{VERSION}}" ]; then
        echo "✅ pyproject.toml version: $TOML_VERSION"
    else
        echo "❌ pyproject.toml version: $TOML_VERSION (expected {{VERSION}})"
        ERRORS=$((ERRORS + 1))
    fi
    
    # Check CHANGELOG
    if grep -q "## \[{{VERSION}}\]" CHANGELOG.md; then
        echo "✅ CHANGELOG.md has entry for {{VERSION}}"
    else
        echo "❌ CHANGELOG.md missing entry for {{VERSION}}"
        ERRORS=$((ERRORS + 1))
    fi
    
    # Check git status
    if git diff-index --quiet HEAD --; then
        echo "✅ No uncommitted changes"
    else
        echo "❌ Uncommitted changes present"
        ERRORS=$((ERRORS + 1))
    fi
    
    # Check if tag exists
    if git rev-parse "v{{VERSION}}" >/dev/null 2>&1; then
        echo "⚠️  Tag v{{VERSION}} already exists"
    else
        echo "✅ Tag v{{VERSION}} not yet created"
    fi
    
    echo ""
    if [ $ERRORS -eq 0 ]; then
        echo "✅ All checks passed! Ready for: just release {{VERSION}}"
    else
        echo "❌ $ERRORS error(s) found. Fix before releasing."
        exit 1
    fi
