#!/usr/bin/env bash
# =============================================================================
# Tale — Container Vulnerability Scanning (Trivy)
# =============================================================================
# Scans all Docker images for known vulnerabilities using Trivy.
#
# Usage:
#   bash tests/container-vulnerability-scan.sh
#   bun run docker:test:vulnerability
#
# Environment variables:
#   VULNERABILITY_SEVERITY     - Severity threshold (default: HIGH,CRITICAL)
#   VULNERABILITY_EXIT_CODE    - Exit code on findings (default: 0 = non-blocking)
#   TRIVY_OUTPUT_DIR  - Directory for scan reports (default: ./trivy-reports)
#
# Prerequisites:
#   - Trivy installed: https://aquasecurity.github.io/trivy/latest/getting-started/installation/
#   - Images must be built first
# =============================================================================

set -euo pipefail

PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
COMPOSE_CMD="docker compose -f compose.yml -f compose.test.yml --env-file .env.test -p tale-test"
SEVERITY="${VULNERABILITY_SEVERITY:-HIGH,CRITICAL}"
EXIT_CODE="${VULNERABILITY_EXIT_CODE:-0}"
OUTPUT_DIR="${TRIVY_OUTPUT_DIR:-${PROJECT_ROOT}/trivy-reports}"
IGNOREFILE="${PROJECT_ROOT}/.trivyignore"

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

SERVICES=(crawler rag platform db proxy)
SCAN_FAILED=0
TOTAL_VULNERABILITIES=0

header() {
    echo ""
    echo -e "${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BOLD}║  $1${NC}"
    echo -e "${BOLD}╚══════════════════════════════════════════════════════════╝${NC}"
}

# =============================================================================
# Check Trivy is installed
# =============================================================================
if ! command -v trivy &>/dev/null; then
    echo -e "${RED}Error: trivy is not installed${NC}"
    echo ""
    echo "Install Trivy:"
    echo "  curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin"
    echo ""
    echo "Or via Docker:"
    echo "  docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image <image>"
    echo ""
    exit 1
fi

# =============================================================================
# Create output directory
# =============================================================================
mkdir -p "${OUTPUT_DIR}"

# =============================================================================
# Get image names
# =============================================================================
cd "${PROJECT_ROOT}"

header "Vulnerability Scan (severity: ${SEVERITY})"
echo -e "  Reports: ${OUTPUT_DIR}"
echo ""

declare -A IMAGES
for svc in "${SERVICES[@]}"; do
    img=$(${COMPOSE_CMD} config --images 2>"${OUTPUT_DIR}/compose-config.log" | grep "${svc}" | head -1)
    if [ -z "$img" ]; then
        echo -e "  ${YELLOW}⚠ ${svc}: image not found (skipping)${NC}"
        continue
    fi
    IMAGES[$svc]="$img"
done

# =============================================================================
# Scan each image
# =============================================================================
echo ""
printf "  ${BOLD}%-12s  %-8s  %-8s  %-8s  %-8s${NC}\n" "SERVICE" "CRITICAL" "HIGH" "MEDIUM" "LOW"
echo "  ──────────  ────────  ────────  ────────  ────────"

IGNOREFILE_ARG=""
if [ -f "$IGNOREFILE" ] && grep -qvE '^\s*(#|$)' "$IGNOREFILE" 2>/dev/null; then
    IGNOREFILE_ARG="--ignorefile ${IGNOREFILE}"
fi

for svc in "${SERVICES[@]}"; do
    img="${IMAGES[$svc]:-}"
    [ -z "$img" ] && continue

    # Single scan producing JSON (derive all outputs from this)
    vulnerability_json_file="${OUTPUT_DIR}/${svc}-report.json"
    trivy image \
        --severity "CRITICAL,HIGH,MEDIUM,LOW" \
        --format json \
        --output "${vulnerability_json_file}" \
        ${IGNOREFILE_ARG:-} \
        "$img" 2>/dev/null
    scan_exit=$?

    # Generate table report from JSON
    trivy convert --format table --output "${OUTPUT_DIR}/${svc}-report.txt" "${vulnerability_json_file}" 2>/dev/null || true

    # Generate SARIF for GitHub Security tab
    trivy convert --format sarif --output "${OUTPUT_DIR}/${svc}-report.sarif" "${vulnerability_json_file}" 2>/dev/null || true

    # Count vulnerabilities by severity
    critical=$(grep -o '"Severity": "CRITICAL"' "${vulnerability_json_file}" 2>/dev/null | wc -l || echo "0")
    high=$(grep -o '"Severity": "HIGH"' "${vulnerability_json_file}" 2>/dev/null | wc -l || echo "0")
    medium=$(grep -o '"Severity": "MEDIUM"' "${vulnerability_json_file}" 2>/dev/null | wc -l || echo "0")
    low=$(grep -o '"Severity": "LOW"' "${vulnerability_json_file}" 2>/dev/null | wc -l || echo "0")

    svc_total=$((critical + high))
    TOTAL_VULNERABILITIES=$((TOTAL_VULNERABILITIES + svc_total))

    if [ $critical -gt 0 ]; then
        printf "  ${RED}%-12s  %-8s  %-8s  %-8s  %-8s${NC}\n" "$svc" "$critical" "$high" "$medium" "$low"
    elif [ $high -gt 0 ]; then
        printf "  ${YELLOW}%-12s  %-8s  %-8s  %-8s  %-8s${NC}\n" "$svc" "$critical" "$high" "$medium" "$low"
    else
        printf "  ${GREEN}%-12s  %-8s  %-8s  %-8s  %-8s${NC}\n" "$svc" "$critical" "$high" "$medium" "$low"
    fi

    if [ $scan_exit -ne 0 ]; then
        SCAN_FAILED=1
    fi
done

# =============================================================================
# Summary
# =============================================================================
echo ""
echo -e "${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}║           VULNERABILITY SCAN SUMMARY                    ║${NC}"
echo -e "${BOLD}╠══════════════════════════════════════════════════════════╣${NC}"
echo -e "  Severity filter: ${SEVERITY}"
echo -e "  Total HIGH+CRITICAL: ${TOTAL_VULNERABILITIES}"
echo -e "  Reports saved to: ${OUTPUT_DIR}/"
echo -e "  Exit code policy: ${EXIT_CODE} (0=advisory, 1=blocking)"

if [ $TOTAL_VULNERABILITIES -eq 0 ]; then
    echo ""
    echo -e "  ${GREEN}${BOLD}🎉 NO HIGH/CRITICAL VULNERABILITIES FOUND${NC}"
elif [ "$EXIT_CODE" = "0" ]; then
    echo ""
    echo -e "  ${YELLOW}${BOLD}⚠ Vulnerabilities found (non-blocking mode)${NC}"
    echo -e "  ${YELLOW}Set VULNERABILITY_EXIT_CODE=1 to make this blocking${NC}"
fi

echo -e "${BOLD}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""

# Add trivy-reports to .gitignore reminder
if ! grep -q "trivy-reports" "${PROJECT_ROOT}/.gitignore" 2>/dev/null; then
    echo -e "${YELLOW}Tip: Add 'trivy-reports/' to .gitignore${NC}"
fi

exit $SCAN_FAILED
