#!/bin/sh
# nanodock - Pre-push hook
# Runs the full quality gate before pushing to remote.
# This mirrors the CI checks so issues are caught locally before a PR.
#
# Install: copy this file to .git/hooks/pre-push (or run scripts/install-hooks.sh)
#          chmod +x .git/hooks/pre-push  (Linux/macOS)
#
# What it checks:
#   1. cargo fmt --check   - formatting
#   2. cross-target clippy - lint violations across Linux + Windows targets
#   3. cargo test          - all tests pass
#   4. cargo bench --no-run - gungraun benchmarks compile
#   5. cargo build         - library compiles
#   6. cargo doc           - documentation builds with CI rustdoc flags
#   7. cargo deny check    - dependency audit (if cargo-deny is installed)

set -e

ensure_cargo() {
    if command -v cargo >/dev/null 2>&1; then
        return 0
    fi

    # Git can execute hooks with a reduced PATH outside the user's shell init.
    if [ -f "$HOME/.cargo/env" ]; then
        . "$HOME/.cargo/env"
    fi

    if command -v cargo >/dev/null 2>&1; then
        return 0
    fi

    if [ -x "$HOME/.cargo/bin/cargo" ]; then
        PATH="$HOME/.cargo/bin:$PATH"
        export PATH
        return 0
    fi

    echo ""
    echo "✗ RUST TOOLCHAIN NOT FOUND"
    echo "  cargo is not available in the git hook environment."
    echo "  Install Rust or source ~/.cargo/env, then try again."
    exit 1
}

ensure_cargo

echo "╔══════════════════════════════════════════╗"
echo "║     nanodock Pre-Push Quality Gate        ║"
echo "╚══════════════════════════════════════════╝"
echo ""

# Gate 1: Formatting
echo "→ [1/7] Checking formatting..."
if ! cargo fmt --all -- --check; then
    echo ""
    echo "✗ FORMATTING FAILED"
    echo "  Run: cargo fmt"
    echo "  Then try pushing again."
    exit 1
fi
echo "  ✓ Formatting OK"

# Gate 2: Clippy across the supported Linux + Windows targets
echo "→ [2/7] Running cross-target clippy..."
if ! sh scripts/check-platform-clippy.sh; then
    echo ""
    echo "✗ CLIPPY FAILED"
    echo "  Fix the lint errors above or install the missing rustup targets,"
    echo "  then try pushing again."
    exit 1
fi
echo "  ✓ Cross-target clippy OK"

# Gate 3: Tests
echo "→ [3/7] Running tests..."
if ! cargo test --lib --tests; then
    echo ""
    echo "✗ TESTS FAILED"
    echo "  Fix the failing unit or integration tests, then try pushing again."
    exit 1
fi

if ! cargo test --doc; then
    echo ""
    echo "✗ TESTS FAILED"
    echo "  Fix the failing doctests, then try pushing again."
    exit 1
fi
echo "  ✓ Tests OK"

# Gate 4: Benchmarks compile on all platforms. Actual execution requires
# valgrind plus gungraun-runner and is enforced in Linux CI.
echo "→ [4/7] Compiling benchmarks..."
if ! cargo bench --no-run; then
    echo ""
    echo "✗ BENCHMARK COMPILE FAILED"
    echo "  Fix the benchmark build errors, then try pushing again."
    exit 1
fi
echo "  ✓ Benchmarks OK"

# Gate 5: Library build
echo "→ [5/7] Building library..."
if ! cargo build; then
    echo ""
    echo "✗ BUILD FAILED"
    echo "  Fix the build errors, then try pushing again."
    exit 1
fi
echo "  ✓ Build OK"

# Gate 6: Documentation
echo "→ [6/7] Building docs..."
if ! RUSTDOCFLAGS="-D warnings -D rustdoc::bare_urls -D rustdoc::invalid_rust_codeblocks -D rustdoc::private_intra_doc_links -D rustdoc::unescaped_backticks" cargo doc --no-deps; then
    echo ""
    echo "✗ DOCUMENTATION BUILD FAILED"
    echo "  Fix the doc errors, then try pushing again."
    exit 1
fi
echo "  ✓ Docs OK"

# Gate 7: Dependency audit (optional - only if cargo-deny is installed)
echo "→ [7/7] Auditing dependencies..."
if command -v cargo-deny >/dev/null 2>&1; then
    if ! cargo deny check 2>/dev/null; then
        # Advisory DB fetch can fail due to stale cache; clear and retry
        echo "  ⚠ First attempt failed - clearing advisory-db cache and retrying..."
        rm -rf "$HOME/.cargo/advisory-dbs" "$HOME/.cargo/advisory-db" 2>/dev/null
        if ! cargo deny check 2>/dev/null; then
            echo ""
            echo "⚠ DEPENDENCY AUDIT FAILED (non-blocking)"
            echo "  CI will enforce this check on the pull request."
            echo "  To debug locally: cargo deny check"
        else
            echo "  ✓ Dependency audit OK (after cache clear)"
        fi
    else
        echo "  ✓ Dependency audit OK"
    fi
else
    echo "  ⊘ cargo-deny not installed, skipping (install: cargo install cargo-deny)"
fi

echo ""
echo "✓ All quality gates passed. Pushing..."
