#!/bin/bash

# Comprehensive test suite for create_or_update tools
# Tests: create_or_update_dataset, create_or_update_location, create_or_update_cluster, create_or_update_pattern
# Usage: ./test_tools.sh [db_path]
# Default: ../db/test.duckdb (ALWAYS USE TEST DATABASE!)

# Get absolute paths before changing directory
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
DB_PATH="${1:-$PROJECT_DIR/db/test.duckdb}"

if [ ! -f "$DB_PATH" ]; then
    echo "Error: Database not found at $DB_PATH"
    exit 1
fi

echo "Testing create_or_update tools with database: $DB_PATH"
echo "======================================================="
echo ""

# Navigate to the project directory where skraak_mcp binary is located
cd "$PROJECT_DIR" || exit 1

if [ ! -f "./skraak_mcp" ]; then
    echo "Error: skraak_mcp binary not found. Run 'go build' first."
    exit 1
fi

# Function to send MCP request
send_request() {
    local method="$1"
    local params="$2"

    (
        echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
        sleep 0.2
        echo "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"$method\",\"params\":$params}"
        sleep 0.5
    ) | timeout 10 ./skraak_mcp "$DB_PATH" 2>&1 | grep '"id":2' | head -1
}

echo "=== PART 1: CREATE MODE (no id provided) ==="
echo ""

# Test 1: Create cyclic recording pattern
echo "Test 1: Create pattern (valid)"
echo "-------------------------------"
PATTERN_RESULT=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"record_seconds":120,"sleep_seconds":300}}')
PATTERN_ID=$(echo "$PATTERN_RESULT" | jq -r '.result.structuredContent.pattern.id // empty')
if [ -n "$PATTERN_ID" ]; then
    echo "✓ Created pattern: $PATTERN_ID (120s record, 300s sleep)"
else
    echo "✗ Failed to create pattern"
    echo "$PATTERN_RESULT" | jq '.'
fi
echo ""

# Test 2: Create pattern with invalid values (should fail)
echo "Test 2: Create pattern with negative values (should fail)"
echo "----------------------------------------------------------"
INVALID_PATTERN=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"record_seconds":-10,"sleep_seconds":300}}')
ERROR=$(echo "$INVALID_PATTERN" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
    echo "✓ Correctly rejected invalid pattern"
else
    echo "✗ Should have rejected negative values"
fi
echo ""

# Test 3: Create dataset
echo "Test 3: Create dataset (organise type)"
echo "---------------------------------------"
DATASET_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"name":"Test Dataset 2026","description":"Automated test dataset","type":"organise"}}')
DATASET_ID=$(echo "$DATASET_RESULT" | jq -r '.result.structuredContent.dataset.id // empty')
if [ -n "$DATASET_ID" ]; then
    echo "✓ Created dataset: $DATASET_ID"
else
    echo "✗ Failed to create dataset"
    echo "$DATASET_RESULT" | jq '.'
fi
echo ""

# Test 4: Create dataset with invalid type (should fail)
echo "Test 4: Create dataset with invalid type (should fail)"
echo "-------------------------------------------------------"
INVALID_DATASET=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"name":"Bad Dataset","type":"invalid_type"}}')
ERROR=$(echo "$INVALID_DATASET" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
    echo "✓ Correctly rejected invalid dataset type"
else
    echo "✗ Should have rejected invalid type"
fi
echo ""

# Test 5: Create location
echo "Test 5: Create location (Wellington, NZ)"
echo "-----------------------------------------"
LOCATION_RESULT=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"dataset_id":"'"$DATASET_ID"'","name":"Wellington Test Location","latitude":-41.2865,"longitude":174.7762,"timezone_id":"Pacific/Auckland","description":"Test location in Wellington"}}')
LOCATION_ID=$(echo "$LOCATION_RESULT" | jq -r '.result.structuredContent.location.id // empty')
if [ -n "$LOCATION_ID" ]; then
    echo "✓ Created location: $LOCATION_ID"
else
    echo "✗ Failed to create location"
    echo "$LOCATION_RESULT" | jq '.'
fi
echo ""

# Test 6: Create location with invalid coordinates (should fail)
echo "Test 6: Create location with invalid coordinates (should fail)"
echo "---------------------------------------------------------------"
INVALID_LOCATION=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"dataset_id":"'"$DATASET_ID"'","name":"Invalid Location","latitude":999,"longitude":174.7762,"timezone_id":"Pacific/Auckland"}}')
ERROR=$(echo "$INVALID_LOCATION" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
    echo "✓ Correctly rejected invalid coordinates"
else
    echo "✗ Should have rejected invalid latitude"
fi
echo ""

# Test 7: Create cluster
echo "Test 7: Create cluster with pattern"
echo "------------------------------------"
CLUSTER_RESULT=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"dataset_id":"'"$DATASET_ID"'","location_id":"'"$LOCATION_ID"'","name":"Test Cluster A01","sample_rate":250000,"cyclic_recording_pattern_id":"'"$PATTERN_ID"'"}}')
CLUSTER_ID=$(echo "$CLUSTER_RESULT" | jq -r '.result.structuredContent.cluster.id // empty')
if [ -n "$CLUSTER_ID" ]; then
    echo "✓ Created cluster: $CLUSTER_ID"
else
    echo "✗ Failed to create cluster"
    echo "$CLUSTER_RESULT" | jq '.'
fi
echo ""

# Test 8: Create cluster with invalid sample rate (should fail)
echo "Test 8: Create cluster with invalid sample rate (should fail)"
echo "--------------------------------------------------------------"
INVALID_CLUSTER=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"dataset_id":"'"$DATASET_ID"'","location_id":"'"$LOCATION_ID"'","name":"Bad Cluster","sample_rate":-1000}}')
ERROR=$(echo "$INVALID_CLUSTER" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
    echo "✓ Correctly rejected invalid sample rate"
else
    echo "✗ Should have rejected negative sample rate"
fi
echo ""

echo "=== PART 2: UPDATE MODE (id provided) ==="
echo ""

# Test 9: Update dataset name and description
echo "Test 9: Update dataset name and description"
echo "--------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"'"$DATASET_ID"'","name":"Updated Test Dataset","description":"Updated description after test"}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.dataset.id // empty')
if [ -n "$SUCCESS" ]; then
    echo "✓ Successfully updated dataset"
else
    echo "✗ Failed to update dataset"
    echo "$UPDATE_RESULT" | jq '.'
fi
echo ""

# Test 10: Update dataset type
echo "Test 10: Update dataset type to 'train'"
echo "---------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"'"$DATASET_ID"'","type":"train"}}')
UPDATED_TYPE=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.dataset.type // empty')
if [ "$UPDATED_TYPE" = "train" ]; then
    echo "✓ Successfully updated dataset type to 'train'"
else
    echo "✗ Failed to update dataset type"
    echo "$UPDATE_RESULT" | jq '.'
fi
echo ""

# Test 11: Update location coordinates
echo "Test 11: Update location coordinates and name"
echo "----------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"id":"'"$LOCATION_ID"'","name":"Updated Wellington Location","latitude":-41.2900,"longitude":174.7800}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.location.id // empty')
if [ -n "$SUCCESS" ]; then
    echo "✓ Successfully updated location"
else
    echo "✗ Failed to update location"
    echo "$UPDATE_RESULT" | jq '.'
fi
echo ""

# Test 12: Update cluster metadata
echo "Test 12: Update cluster name and sample rate"
echo "---------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"id":"'"$CLUSTER_ID"'","name":"Updated Cluster A01","sample_rate":384000,"description":"Updated cluster description"}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.cluster.id // empty')
if [ -n "$SUCCESS" ]; then
    echo "✓ Successfully updated cluster"
else
    echo "✗ Failed to update cluster"
    echo "$UPDATE_RESULT" | jq '.'
fi
echo ""

# Test 13: Update recording pattern
echo "Test 13: Update recording pattern durations"
echo "--------------------------------------------"
echo -n "Getting existing pattern from database... "
EXISTING_PATTERN=$(send_request "tools/call" '{"name":"execute_sql","arguments":{"query":"SELECT id, record_s, sleep_s FROM cyclic_recording_pattern WHERE active = true ORDER BY created_at DESC LIMIT 1"}}')
EXISTING_PATTERN_ID=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].id // empty')
CURRENT_RECORD=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].record_s // empty' | sed 's/"//g')
CURRENT_SLEEP=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].sleep_s // empty' | sed 's/"//g')

if [ -n "$EXISTING_PATTERN_ID" ] && [ -n "$CURRENT_RECORD" ] && [ -n "$CURRENT_SLEEP" ]; then
    echo "found $EXISTING_PATTERN_ID (${CURRENT_RECORD}s/${CURRENT_SLEEP}s)"
    
    # Generate unique values based on current timestamp to avoid duplicates
    TIMESTAMP_OFFSET=$(($(date +%s) % 100))
    NEW_RECORD=$((CURRENT_RECORD + TIMESTAMP_OFFSET))
    NEW_SLEEP=$((CURRENT_SLEEP + TIMESTAMP_OFFSET))
    
    UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"id":"'"$EXISTING_PATTERN_ID"'","record_seconds":'"$NEW_RECORD"',"sleep_seconds":'"$NEW_SLEEP"'}}')
    SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.pattern.id // empty')
    if [ -n "$SUCCESS" ]; then
        echo "✓ Successfully updated pattern (${NEW_RECORD}s record, ${NEW_SLEEP}s sleep)"
    else
        echo "✗ Failed to update pattern"
        echo "$UPDATE_RESULT" | jq '.'
    fi
else
    echo "✗ Could not find existing pattern to update"
fi
echo ""

# Test 14: Update with invalid ID (should fail)
echo "Test 14: Update with non-existent dataset ID (should fail)"
echo "-----------------------------------------------------------"
INVALID_UPDATE=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"INVALID_ID_123","name":"Should Fail"}}')
ERROR=$(echo "$INVALID_UPDATE" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
    echo "✓ Correctly rejected invalid dataset ID"
else
    echo "✗ Should have rejected invalid ID"
fi
echo ""

echo "=== TEST SUMMARY ==="
echo "All create_or_update tool tests complete!"
echo "Check output above for any ✗ failures"
echo ""