#!/bin/bash
# AutoWorkflow Post-Edit Hook
# Runs on: PostToolUse for Write/Edit tools
# Purpose: Auto-run verification with loop tracking
#
# This hook implements verify_loop from system/loops.md
# It tracks iterations and enforces the verify_gate

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'

# Project directory (use env var if set, otherwise current directory)
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"

# Source the logger
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/logger.sh" 2>/dev/null || true

# State directory
STATE_DIR="$PROJECT_DIR/.claude/.autoworkflow"
mkdir -p "$STATE_DIR"

# Configuration
MAX_ITERATIONS=10
VERIFY_ITERATION_FILE="$STATE_DIR/verify-iteration"
VERIFY_STATUS_FILE="$STATE_DIR/verify-status"
CHANGED_FILES_FILE="$STATE_DIR/changed-files"
PHASE_FILE="$STATE_DIR/phase"

# Get current iteration count
get_iteration() {
    if [ -f "$VERIFY_ITERATION_FILE" ]; then
        cat "$VERIFY_ITERATION_FILE"
    else
        echo "0"
    fi
}

# Increment iteration
increment_iteration() {
    local current=$(get_iteration)
    local next=$((current + 1))
    echo "$next" > "$VERIFY_ITERATION_FILE"
    echo "$next"
}

# Reset iteration counter
reset_iteration() {
    echo "0" > "$VERIFY_ITERATION_FILE"
}

# Track changed file
track_file() {
    local file="$1"
    if [ -n "$file" ]; then
        echo "$file" >> "$CHANGED_FILES_FILE"
        # Remove duplicates
        if [ -f "$CHANGED_FILES_FILE" ]; then
            sort -u "$CHANGED_FILES_FILE" -o "$CHANGED_FILES_FILE"
        fi
    fi
}

# Get current phase
get_phase() {
    if [ -f "$PHASE_FILE" ]; then
        cat "$PHASE_FILE"
    else
        echo "UNKNOWN"
    fi
}

# Set phase
set_phase() {
    echo "$1" > "$PHASE_FILE"
}

# Print header
print_header() {
    local iteration=$(get_iteration)
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo -e "${BOLD}AUTOWORKFLOW: VERIFY LOOP${NC} ${DIM}(Iteration $iteration/$MAX_ITERATIONS)${NC}"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
}

# Detect project type
detect_project_type() {
    if [ -f "package.json" ]; then
        echo "node"
    elif [ -f "composer.json" ]; then
        echo "php"
    elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ] || [ -f "setup.py" ]; then
        echo "python"
    elif [ -f "Cargo.toml" ]; then
        echo "rust"
    elif [ -f "go.mod" ]; then
        echo "go"
    elif [ -f "Gemfile" ]; then
        echo "ruby"
    elif [ -f "build.gradle" ] || [ -f "pom.xml" ]; then
        echo "java"
    else
        echo "unknown"
    fi
}

# Run verification for Node.js projects
run_verify_node() {
    local has_verify=false
    local has_typecheck=false
    local has_lint=false

    grep -q '"verify"' package.json 2>/dev/null && has_verify=true
    grep -q '"typecheck"' package.json 2>/dev/null && has_typecheck=true
    grep -q '"lint"' package.json 2>/dev/null && has_lint=true

    if [ "$has_verify" = true ]; then
        echo -e "${CYAN}Running:${NC} npm run verify"
        echo ""
        npm run verify 2>&1
        return $?
    elif [ "$has_typecheck" = true ] || [ "$has_lint" = true ]; then
        local exit_code=0

        if [ "$has_typecheck" = true ]; then
            echo -e "${CYAN}Running:${NC} npm run typecheck"
            if ! npm run typecheck 2>&1; then
                exit_code=1
            fi
        fi

        if [ "$has_lint" = true ]; then
            echo ""
            echo -e "${CYAN}Running:${NC} npm run lint"
            if ! npm run lint 2>&1; then
                exit_code=1
            fi
        fi

        return $exit_code
    fi
    return 0
}

# Run verification for PHP projects
run_verify_php() {
    local exit_code=0

    # Check for PHPStan
    if [ -f "phpstan.neon" ] || [ -f "phpstan.neon.dist" ] || grep -q '"phpstan"' composer.json 2>/dev/null; then
        echo -e "${CYAN}Running:${NC} ./vendor/bin/phpstan analyse"
        if ! ./vendor/bin/phpstan analyse 2>&1; then
            exit_code=1
        fi
    fi

    # Check for PHP CS Fixer or PHP_CodeSniffer
    if [ -f ".php-cs-fixer.php" ] || [ -f ".php-cs-fixer.dist.php" ]; then
        echo ""
        echo -e "${CYAN}Running:${NC} ./vendor/bin/php-cs-fixer fix --dry-run --diff"
        if ! ./vendor/bin/php-cs-fixer fix --dry-run --diff 2>&1; then
            exit_code=1
        fi
    elif [ -f "phpcs.xml" ] || [ -f "phpcs.xml.dist" ]; then
        echo ""
        echo -e "${CYAN}Running:${NC} ./vendor/bin/phpcs"
        if ! ./vendor/bin/phpcs 2>&1; then
            exit_code=1
        fi
    fi

    # Check for composer scripts
    if grep -q '"test"' composer.json 2>/dev/null; then
        echo ""
        echo -e "${CYAN}Running:${NC} composer test"
        if ! composer test 2>&1; then
            exit_code=1
        fi
    fi

    if [ $exit_code -eq 0 ] && ! grep -q '"phpstan"' composer.json 2>/dev/null && ! [ -f ".php-cs-fixer.php" ] && ! [ -f "phpcs.xml" ]; then
        echo -e "${YELLOW}⚠${NC} No PHP verification tools detected (PHPStan, PHP-CS-Fixer, PHPCS)"
        echo "  Consider adding: composer require --dev phpstan/phpstan"
    fi

    return $exit_code
}

# Run verification for Python projects
run_verify_python() {
    local exit_code=0

    # Check for mypy
    if [ -f "mypy.ini" ] || [ -f "setup.cfg" ] || [ -f "pyproject.toml" ]; then
        if command -v mypy &> /dev/null; then
            echo -e "${CYAN}Running:${NC} mypy ."
            if ! mypy . 2>&1; then
                exit_code=1
            fi
        fi
    fi

    # Check for ruff or flake8
    if command -v ruff &> /dev/null; then
        echo ""
        echo -e "${CYAN}Running:${NC} ruff check ."
        if ! ruff check . 2>&1; then
            exit_code=1
        fi
    elif command -v flake8 &> /dev/null; then
        echo ""
        echo -e "${CYAN}Running:${NC} flake8 ."
        if ! flake8 . 2>&1; then
            exit_code=1
        fi
    fi

    if [ $exit_code -eq 0 ] && ! command -v mypy &> /dev/null && ! command -v ruff &> /dev/null; then
        echo -e "${YELLOW}⚠${NC} No Python verification tools detected (mypy, ruff, flake8)"
        echo "  Consider adding: pip install mypy ruff"
    fi

    return $exit_code
}

# Run verification for Rust projects
run_verify_rust() {
    local exit_code=0

    echo -e "${CYAN}Running:${NC} cargo check"
    if ! cargo check 2>&1; then
        exit_code=1
    fi

    echo ""
    echo -e "${CYAN}Running:${NC} cargo clippy"
    if ! cargo clippy -- -D warnings 2>&1; then
        exit_code=1
    fi

    return $exit_code
}

# Run verification for Go projects
run_verify_go() {
    local exit_code=0

    echo -e "${CYAN}Running:${NC} go build ./..."
    if ! go build ./... 2>&1; then
        exit_code=1
    fi

    echo ""
    echo -e "${CYAN}Running:${NC} go vet ./..."
    if ! go vet ./... 2>&1; then
        exit_code=1
    fi

    if command -v golangci-lint &> /dev/null; then
        echo ""
        echo -e "${CYAN}Running:${NC} golangci-lint run"
        if ! golangci-lint run 2>&1; then
            exit_code=1
        fi
    fi

    return $exit_code
}

# Run verification based on project type
run_verify() {
    local project_type=$(detect_project_type)

    echo -e "${DIM}Detected project type: ${project_type}${NC}"
    echo ""

    case "$project_type" in
        node)
            run_verify_node
            return $?
            ;;
        php)
            run_verify_php
            return $?
            ;;
        python)
            run_verify_python
            return $?
            ;;
        rust)
            run_verify_rust
            return $?
            ;;
        go)
            run_verify_go
            return $?
            ;;
        *)
            echo -e "${YELLOW}⚠${NC} Unknown project type - no verification available"
            echo "  Supported: Node.js, PHP, Python, Rust, Go"
            return 0
            ;;
    esac
}

# Main execution
main() {
    aw_log_hook "post-edit.sh" "START"

    local current_phase=$(get_phase)

    # Track that we're in VERIFY phase
    set_phase "VERIFY"

    # Get current iteration and increment
    local iteration=$(increment_iteration)
    aw_log_verify "$iteration/$MAX_ITERATIONS" "STARTED"

    # Check if we've exceeded max iterations
    if [ "$iteration" -gt "$MAX_ITERATIONS" ]; then
        echo ""
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo -e "${RED}${BOLD}⛔ MAX ITERATIONS REACHED${NC}"
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo ""
        echo "Verification has failed $MAX_ITERATIONS times."
        echo "Manual intervention required."
        echo ""
        echo "Options:"
        echo "  1. Fix remaining errors manually"
        echo "  2. Reset counter: rm $VERIFY_ITERATION_FILE"
        echo ""
        echo "BLOCKED" > "$VERIFY_STATUS_FILE"
        aw_log_verify "$iteration/$MAX_ITERATIONS" "BLOCKED" "max iterations reached"
        # Don't exit with error - let Claude continue but report the issue
        exit 0
    fi

    print_header

    # Run verification
    echo "Checking TypeScript + ESLint..."
    echo ""

    if run_verify; then
        echo ""
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo -e "${GREEN}${BOLD}✅ VERIFICATION PASSED${NC}"
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo ""

        # Reset iteration counter on success
        reset_iteration

        # Update status
        echo "PASSED" > "$VERIFY_STATUS_FILE"
        aw_log_verify "$iteration/$MAX_ITERATIONS" "PASSED" "0 errors"

        # Check if this was a feature/refactor that needs audit
        local task_type=""
        if [ -f "$STATE_DIR/task-type" ]; then
            task_type=$(cat "$STATE_DIR/task-type")
        fi

        if [ "$task_type" = "feature" ] || [ "$task_type" = "refactor" ]; then
            echo "Task type: $task_type → AUDIT phase required"
            echo ""
            echo "Next: Run audits before commit"
            echo "  npm run audit:ui"
            echo "  npm run audit:cycles"
            set_phase "AUDIT"
        else
            echo "Ready to proceed to COMMIT."
            set_phase "PRE_COMMIT"
        fi
        echo ""

    else
        echo ""
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo -e "${RED}${BOLD}❌ VERIFICATION FAILED${NC} ${DIM}(Iteration $iteration/$MAX_ITERATIONS)${NC}"
        echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
        echo ""

        # Update status
        echo "FAILED" > "$VERIFY_STATUS_FILE"
        echo "$iteration" > "$VERIFY_ITERATION_FILE"
        aw_log_verify "$iteration/$MAX_ITERATIONS" "FAILED" "errors found"

        echo "Fix the errors above and save the file."
        echo "Verification will re-run automatically."
        echo ""
        echo -e "${DIM}Remaining attempts: $((MAX_ITERATIONS - iteration))${NC}"
        echo ""

        # Enter FIX phase
        set_phase "FIX"
    fi

    aw_log_hook "post-edit.sh" "COMPLETE"
}

main
