#!/usr/bin/env bash
set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
OPTIX_CLI="$PROJECT_ROOT/optix.sh"
export OPTIX_DIR="$PROJECT_ROOT/.optix-test"

passed=0
failed=0

setup() {
    rm -rf "$OPTIX_DIR"
    mkdir -p "$OPTIX_DIR"
}

teardown() {
    rm -rf "$OPTIX_DIR"
}

create_sarif_file() {
    local name="$1"
    local error_count="${2:-0}"
    local warning_count="${3:-0}"
    local note_count="${4:-0}"

    local results="["
    local first=true

    for ((i=0; i<error_count; i++)); do
        [[ "$first" == "true" ]] && first=false || results+=","
        results+='{
            "ruleId": "ERR'$i'",
            "level": "error",
            "message": {"text": "Error finding '$i'"},
            "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/file.py"}, "region": {"startLine": '$((i+1))'} }}]
        }'
    done

    for ((i=0; i<warning_count; i++)); do
        [[ "$first" == "true" ]] && first=false || results+=","
        results+='{
            "ruleId": "WARN'$i'",
            "level": "warning",
            "message": {"text": "Warning finding '$i'"},
            "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/file.py"}, "region": {"startLine": '$((i+10))'} }}]
        }'
    done

    for ((i=0; i<note_count; i++)); do
        [[ "$first" == "true" ]] && first=false || results+=","
        results+='{
            "ruleId": "NOTE'$i'",
            "level": "note",
            "message": {"text": "Note finding '$i'"},
            "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/file.py"}, "region": {"startLine": '$((i+20))'} }}]
        }'
    done

    results+="]"

    cat > "$OPTIX_DIR/$name" << EOF
{
  "\$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [{
    "tool": {"driver": {"name": "Optix Test", "version": "0.1.0"}},
    "results": $results
  }]
}
EOF
}

test_exit_code() {
    local name="$1"
    local expected_exit="$2"
    shift 2

    set +e
    "$@" > /dev/null 2>&1
    local actual_exit=$?
    set -e

    if [[ "$actual_exit" -eq "$expected_exit" ]]; then
        echo "✓ $name"
        passed=$((passed + 1))
    else
        echo "✗ $name (expected exit $expected_exit, got $actual_exit)"
        failed=$((failed + 1))
    fi
}

test_output_contains() {
    local name="$1"
    local expected_pattern="$2"
    shift 2

    local output
    output=$("$@" 2>&1) || true

    if echo "$output" | grep -q "$expected_pattern"; then
        echo "✓ $name"
        passed=$((passed + 1))
    else
        echo "✗ $name (output does not contain '$expected_pattern')"
        failed=$((failed + 1))
    fi
}

echo "=== Optix CLI Tests ==="
echo ""

echo "--- Help and Version ---"
test_exit_code "help command exits 0" 0 "$OPTIX_CLI" help
test_exit_code "--help flag exits 0" 0 "$OPTIX_CLI" --help
test_exit_code "version command exits 0" 0 "$OPTIX_CLI" version
test_output_contains "version shows version number" "0.1.0" "$OPTIX_CLI" version
echo ""

echo "--- Missing Directory ---"
teardown
test_exit_code "check without .optix dir exits 3" 3 "$OPTIX_CLI" check
test_exit_code "list without .optix dir exits 3" 3 "$OPTIX_CLI" list
test_exit_code "summary without .optix dir exits 3" 3 "$OPTIX_CLI" summary
echo ""

echo "--- No SARIF Files ---"
setup
test_exit_code "check with empty .optix dir exits 3" 3 "$OPTIX_CLI" check
test_exit_code "list with empty .optix dir exits 3" 3 "$OPTIX_CLI" list
echo ""

echo "--- Pass/Fail Logic ---"
setup
create_sarif_file "SARIF_security_001.sarif.json" 0 0 1
test_exit_code "check passes with only note (below high threshold)" 0 "$OPTIX_CLI" check

setup
create_sarif_file "SARIF_security_001.sarif.json" 0 1 0
test_exit_code "check passes with only warning (below high threshold)" 0 "$OPTIX_CLI" check

setup
create_sarif_file "SARIF_security_001.sarif.json" 1 0 0
test_exit_code "check fails with error (at high threshold)" 1 "$OPTIX_CLI" check

setup
create_sarif_file "SARIF_security_001.sarif.json" 1 0 0
test_exit_code "check passes with error when --fail-on critical" 0 "$OPTIX_CLI" check --fail-on critical

setup
create_sarif_file "SARIF_security_001.sarif.json" 0 1 0
test_exit_code "check fails with warning when --fail-on medium" 1 "$OPTIX_CLI" check --fail-on medium

setup
create_sarif_file "SARIF_security_001.sarif.json" 0 0 1
test_exit_code "check fails with note when --fail-on low" 1 "$OPTIX_CLI" check --fail-on low
echo ""

echo "--- Lens Filtering ---"
setup
create_sarif_file "SARIF_security_001.sarif.json" 1 0 0
create_sarif_file "SARIF_a11y_001.sarif.json" 0 0 1
test_exit_code "check --lens security finds security file" 1 "$OPTIX_CLI" check --lens security
test_exit_code "check --lens a11y finds a11y file" 0 "$OPTIX_CLI" check --lens a11y
test_exit_code "check --lens devops finds no files" 3 "$OPTIX_CLI" check --lens devops
echo ""

echo "--- Output Formats ---"
setup
create_sarif_file "SARIF_security_001.sarif.json" 1 1 1
test_output_contains "text format shows severity counts" "high:" "$OPTIX_CLI" check --format text --fail-on critical
test_output_contains "json format has findings object" '"findings"' "$OPTIX_CLI" check --format json --fail-on critical
test_output_contains "github-actions format has annotations" "::error file=" "$OPTIX_CLI" check --format github-actions --fail-on critical
test_output_contains "github-actions format has group" "::group::" "$OPTIX_CLI" check --format github-actions --fail-on critical
echo ""

echo "--- List Command ---"
setup
create_sarif_file "SARIF_security_001.sarif.json" 2 1 0
test_exit_code "list command exits 0 with files" 0 "$OPTIX_CLI" list
test_output_contains "list shows file name" "SARIF_security_001.sarif.json" "$OPTIX_CLI" list
test_output_contains "list shows findings count" "findings: 3" "$OPTIX_CLI" list
test_output_contains "list shows lens" "lens: security" "$OPTIX_CLI" list
echo ""

echo "--- Summary Command ---"
setup
create_sarif_file "SARIF_security_001.sarif.json" 1 1 1
test_exit_code "summary command exits 0" 0 "$OPTIX_CLI" summary
test_output_contains "summary shows total counts" "Total:" "$OPTIX_CLI" summary
test_output_contains "summary --verbose shows details" "Location:" "$OPTIX_CLI" summary --verbose
echo ""

teardown

echo "=== Results ==="
echo "Passed: $passed"
echo "Failed: $failed"
echo ""

if [[ "$failed" -gt 0 ]]; then
    exit 1
fi
exit 0
