#!/bin/bash
# Shared library for shell test scripts
# Source this file: source ./test_lib.sh

set -euo pipefail

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

# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

# Project paths
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
PRODUCTION_DB="$PROJECT_DIR/db/skraak.duckdb"
DEFAULT_TEST_DB="$PROJECT_DIR/db/test.duckdb"

# Check that skraak binary exists
check_binary() {
    if [ ! -f "$PROJECT_DIR/skraak" ]; then
        echo -e "${RED}Error: skraak binary not found. Run 'go build' first.${NC}"
        exit 1
    fi
}

# Create fresh test database from production
# Returns path to fresh test DB (in /tmp)
fresh_test_db() {
    if [ ! -f "$PRODUCTION_DB" ]; then
        echo -e "${RED}Error: Production database not found at $PRODUCTION_DB${NC}"
        exit 1
    fi

    local test_db="/tmp/skraak_test_$$.duckdb"
    cp "$PRODUCTION_DB" "$test_db"
    echo "$test_db"
}

# Cleanup test database
cleanup_test_db() {
    local db_path="$1"
    if [ -n "$db_path" ] && [ -f "$db_path" ]; then
        rm -f "$db_path"
        # Also remove DuckDB temp files
        rm -f "${db_path}.wal" "${db_path}.tmp" 2>/dev/null || true
    fi
}

# Send MCP request and get response
# Usage: send_request <method> <params_json> [db_path]
send_request() {
    local method="$1"
    local params="$2"
    local db_path="${3:-$DEFAULT_TEST_DB}"

    (
        echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
        sleep 0.5
        echo "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"$method\",\"params\":$params}"
        sleep 1.0
    ) | timeout 20 "$PROJECT_DIR/skraak" mcp --db "$db_path" 2>&1 | grep '"id":2' | head -1
}

# Send multiple MCP requests in one session
# Usage: send_requests <db_path> <request1> <request2> ...
send_requests() {
    local db_path="$1"
    shift

    {
        echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
        sleep 0.5

        local id=2
        for req in "$@"; do
            echo "{\"jsonrpc\":\"2.0\",\"id\":$id,$req}"
            sleep 0.3
            ((id++)) || true
        done
        sleep 1.0
    } | timeout 60 "$PROJECT_DIR/skraak" mcp --db "$db_path" 2>/dev/null
}

# Extract result from MCP response
get_result() {
    echo "$1" | jq -r '.result.structuredContent // .result.content[0].text // empty'
}

# Check if response is an error
is_error() {
    local result="$1"
    local is_err=$(echo "$result" | jq -r '.result.isError // false')
    [ "$is_err" = "true" ]
}

# Run a single test
# Usage: run_test <name> <expected_pass> <actual_result>
run_test() {
    local name="$1"
    local expected_pass="$2"
    local result="$3"

    ((TESTS_RUN++)) || true

    local is_err="false"
    is_err=$(echo "$result" | jq -r '.result.isError // false')

    if [ "$expected_pass" = "true" ]; then
        if [ "$is_err" = "true" ]; then
            echo -e "${RED}${NC} $name (unexpected error)"
            ((TESTS_FAILED++)) || true
        else
            echo -e "${GREEN}${NC} $name"
            ((TESTS_PASSED++)) || true
        fi
    else
        if [ "$is_err" = "true" ]; then
            echo -e "${GREEN}${NC} $name (correctly rejected)"
            ((TESTS_PASSED++)) || true
        else
            echo -e "${RED}${NC} $name (should have failed)"
            ((TESTS_FAILED++)) || true
        fi
    fi
}

# Print test summary
print_summary() {
    echo ""
    echo "=== Summary ==="
    echo -e "Tests run: $TESTS_RUN"
    echo -e "Passed: ${GREEN}$TESTS_PASSED${NC}"
    if [ "$TESTS_FAILED" -gt 0 ]; then
        echo -e "Failed: ${RED}$TESTS_FAILED${NC}"
    else
        echo -e "Failed: $TESTS_FAILED"
    fi

    if [ "$TESTS_FAILED" -gt 0 ]; then
        return 1
    fi
    return 0
}

# Extract ID from create response
get_created_id() {
    local result="$1"
    local entity_type="$2"  # dataset, location, cluster, pattern
    echo "$result" | jq -r ".result.structuredContent.$entity_type.id // empty"
}