#!/usr/bin/env bash
# Pre-release validation script.
#
# Runs all checks required before a release can proceed.
# This is more thorough than dev CI - it's the "go/no-go" gate.
#
# Usage:
#   ./scripts/release-check [--fix]
#
# Options:
#   --fix    Attempt to fix issues (update CHANGELOG, bump version)
#
# Exit codes:
#   0 - All checks passed, ready to release
#   1 - Checks failed, see output for details
#
set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

FIX_MODE=false
if [[ "${1:-}" == "--fix" ]]; then
    FIX_MODE=true
fi

FAILED=0
WARNINGS=0

pass() {
    echo -e "${GREEN}✓${NC} $1"
}

fail() {
    echo -e "${RED}✗${NC} $1"
    FAILED=$((FAILED + 1))
}

warn() {
    echo -e "${YELLOW}!${NC} $1"
    WARNINGS=$((WARNINGS + 1))
}

section() {
    echo ""
    echo "━━━ $1 ━━━"
}

# Get project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"

echo "╔════════════════════════════════════════╗"
echo "║       Release Readiness Check          ║"
echo "╚════════════════════════════════════════╝"

# ─────────────────────────────────────────────────────────────
section "1. Git State"
# ─────────────────────────────────────────────────────────────

# Check for uncommitted changes
if [[ -n "$(git status --porcelain)" ]]; then
    fail "Uncommitted changes detected"
    git status --short
else
    pass "Working directory clean"
fi

# Check we're on the right branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$CURRENT_BRANCH" == "dev" || "$CURRENT_BRANCH" == "main" ]]; then
    pass "On branch: $CURRENT_BRANCH"
else
    warn "On branch '$CURRENT_BRANCH' (expected 'dev' or 'main')"
fi

# Check if up to date with remote
git fetch origin --quiet
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse "origin/$CURRENT_BRANCH" 2>/dev/null || echo "none")
if [[ "$LOCAL" == "$REMOTE" ]]; then
    pass "Branch up to date with origin"
elif [[ "$REMOTE" == "none" ]]; then
    warn "No remote tracking branch"
else
    fail "Branch not in sync with origin (pull or push needed)"
fi

# ─────────────────────────────────────────────────────────────
section "2. Version & Changelog"
# ─────────────────────────────────────────────────────────────

# Extract version from pyproject.toml
VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
if [[ -n "$VERSION" ]]; then
    pass "Version in pyproject.toml: $VERSION"
else
    fail "Could not extract version from pyproject.toml"
fi

# Check CHANGELOG.md exists and has entry for this version
if [[ -f "CHANGELOG.md" ]]; then
    if grep -q "## \[$VERSION\]" CHANGELOG.md; then
        pass "CHANGELOG.md has entry for v$VERSION"
    elif grep -q "## \[Unreleased\]" CHANGELOG.md; then
        if $FIX_MODE; then
            warn "CHANGELOG.md has Unreleased section (would update in --fix mode)"
        else
            fail "CHANGELOG.md has Unreleased but no entry for v$VERSION"
            echo "    Run with --fix to update, or manually add ## [$VERSION] - $(date +%Y-%m-%d)"
        fi
    else
        fail "CHANGELOG.md missing entry for v$VERSION"
    fi
else
    fail "CHANGELOG.md not found"
fi

# Check version doesn't already have a git tag
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
    fail "Tag v$VERSION already exists"
else
    pass "Tag v$VERSION is available"
fi

# ─────────────────────────────────────────────────────────────
section "3. Dependencies & Security"
# ─────────────────────────────────────────────────────────────

# Check for known vulnerabilities
echo "  Running pip-audit..."
if pip-audit --strict 2>/dev/null; then
    pass "No known vulnerabilities in dependencies"
else
    fail "Vulnerabilities detected (run 'pip-audit' for details)"
fi

# Check for secrets
echo "  Scanning for secrets..."
if command -v gitleaks &>/dev/null; then
    if gitleaks detect --source . --no-git --quiet 2>/dev/null; then
        pass "No secrets detected (gitleaks)"
    else
        fail "Potential secrets detected (run 'gitleaks detect' for details)"
    fi
elif command -v trufflehog &>/dev/null; then
    if trufflehog filesystem . --no-update --quiet 2>/dev/null; then
        pass "No secrets detected (trufflehog)"
    else
        fail "Potential secrets detected"
    fi
else
    warn "No secret scanner installed (install gitleaks or trufflehog)"
fi

# Security linting
echo "  Running Bandit..."
if bandit -r src/ -c pyproject.toml --quiet 2>/dev/null; then
    pass "Security linting passed (Bandit)"
else
    fail "Security issues detected (run 'bandit -r src/' for details)"
fi

# ─────────────────────────────────────────────────────────────
section "4. Code Quality"
# ─────────────────────────────────────────────────────────────

# Linting
echo "  Running Ruff..."
if ruff check src/ tests/ --quiet 2>/dev/null; then
    pass "Linting passed (Ruff)"
else
    fail "Linting issues detected (run 'ruff check src/ tests/')"
fi

# Type checking (if configured)
if command -v mypy &>/dev/null && [[ -f "mypy.ini" || -f "pyproject.toml" ]]; then
    echo "  Running mypy..."
    if mypy src/ --quiet 2>/dev/null; then
        pass "Type checking passed (mypy)"
    else
        warn "Type checking issues (run 'mypy src/')"
    fi
fi

# ─────────────────────────────────────────────────────────────
section "5. Test Suite"
# ─────────────────────────────────────────────────────────────

# Run tests with coverage
echo "  Running pytest with coverage..."
if pytest --cov=src --cov-fail-under=100 --quiet 2>/dev/null; then
    pass "All tests passed with 100% coverage"
else
    fail "Tests failed or coverage < 100%"
fi

# ─────────────────────────────────────────────────────────────
section "6. Build Verification"
# ─────────────────────────────────────────────────────────────

# Test that package builds
echo "  Building package..."
rm -rf dist/ build/ *.egg-info
if pip wheel . --no-deps --wheel-dir dist/ --quiet 2>/dev/null; then
    WHEEL=$(ls dist/*.whl 2>/dev/null | head -1)
    if [[ -n "$WHEEL" ]]; then
        pass "Package builds successfully: $(basename "$WHEEL")"
    else
        fail "Wheel not created"
    fi
else
    fail "Package build failed"
fi

# Verify wheel can be installed
echo "  Verifying wheel installation..."
if pip install "$WHEEL" --quiet --dry-run 2>/dev/null; then
    pass "Wheel can be installed"
else
    warn "Wheel installation check failed (may be pip version issue)"
fi

# ─────────────────────────────────────────────────────────────
section "7. Documentation"
# ─────────────────────────────────────────────────────────────

# Check generated files are up to date
if ./scripts/generate-schema --check 2>/dev/null; then
    pass "Schema is up to date"
else
    fail "Schema needs regeneration (run './scripts/generate-schema')"
fi

if ./scripts/generate-architecture --check 2>/dev/null; then
    pass "Architecture docs up to date"
else
    fail "Architecture docs need regeneration"
fi

# ─────────────────────────────────────────────────────────────
section "8. License Compliance"
# ─────────────────────────────────────────────────────────────

# Check dependency licenses (if pip-licenses available)
if command -v pip-licenses &>/dev/null; then
    echo "  Checking dependency licenses..."
    # List of problematic licenses
    PROBLEMATIC="GPL;AGPL;SSPL;BUSL"
    if pip-licenses --format=csv 2>/dev/null | grep -qiE "$PROBLEMATIC"; then
        warn "Some dependencies have copyleft licenses (review manually)"
        pip-licenses --format=markdown | grep -iE "$PROBLEMATIC" || true
    else
        pass "No problematic licenses detected"
    fi
else
    warn "pip-licenses not installed (run 'pip install pip-licenses' for license audit)"
fi

# ─────────────────────────────────────────────────────────────
section "Summary"
# ─────────────────────────────────────────────────────────────

echo ""
if [[ $FAILED -eq 0 ]]; then
    echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║   All checks passed! Ready to release  ║${NC}"
    echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
    if [[ $WARNINGS -gt 0 ]]; then
        echo -e "${YELLOW}($WARNINGS warnings - review recommended)${NC}"
    fi
    echo ""
    echo "Next steps:"
    echo "  1. Review CHANGELOG.md"
    echo "  2. Run: ./scripts/release $VERSION"
    exit 0
else
    echo -e "${RED}╔════════════════════════════════════════╗${NC}"
    echo -e "${RED}║   $FAILED check(s) failed - not ready     ║${NC}"
    echo -e "${RED}╚════════════════════════════════════════╝${NC}"
    echo ""
    echo "Fix the issues above before releasing."
    exit 1
fi
