#!/bin/bash
#
# State Consistency Validator
#
# Validates state consistency for a run using multiple independent checks.
# Applies self-consistency principle with majority voting.
#
# Usage:
#   ./check_state_consistency.sh <run_id>
#   ./check_state_consistency.sh run_20250310_143022
#

set -e

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

# Check arguments
if [ $# -lt 1 ]; then
    echo "Usage: $0 <run_id>"
    echo "Example: $0 run_20250310_143022"
    exit 1
fi

RUN_ID=$1
STATE_FILE=".claude/state/${RUN_ID}.json"

# Check if state file exists
if [ ! -f "$STATE_FILE" ]; then
    echo -e "${RED}ERROR: State file not found: $STATE_FILE${NC}"
    echo ""
    echo "Available runs:"
    ls -1 .claude/state/run_*.json 2>/dev/null | xargs -n1 basename || echo "  None"
    exit 1
fi

# Check if jq is available
if ! command -v jq &> /dev/null; then
    echo -e "${YELLOW}WARNING: jq not found. Using python fallback.${NC}"
    USE_JQ=false
else
    USE_JQ=true
fi

echo "=========================================="
echo "STATE CONSISTENCY VALIDATION"
echo "=========================================="
echo ""
echo "Run ID: $RUN_ID"
echo "State File: $STATE_FILE"
echo ""

# Extract state information
if [ "$USE_JQ" = true ]; then
    SPEC_PATH=$(jq -r '.spec_path' "$STATE_FILE")
    OUTPUT_DIR=$(jq -r '.output_dir' "$STATE_FILE")
    STATUS=$(jq -r '.status' "$STATE_FILE")
    COMPLETED=$(jq -r '.completed_iterations' "$STATE_FILE")
    TOTAL=$(jq -r '.total_count' "$STATE_FILE")
    CREATED=$(jq -r '.created_at' "$STATE_FILE")
    UPDATED=$(jq -r '.updated_at' "$STATE_FILE")
else
    SPEC_PATH=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['spec_path'])")
    OUTPUT_DIR=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['output_dir'])")
    STATUS=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['status'])")
    COMPLETED=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['completed_iterations'])")
    TOTAL=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['total_count'])")
    CREATED=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['created_at'])")
    UPDATED=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['updated_at'])")
fi

echo "Status: $STATUS"
echo "Progress: $COMPLETED of $TOTAL"
echo "Spec: $SPEC_PATH"
echo "Output: $OUTPUT_DIR"
echo "Created: $CREATED"
echo "Updated: $UPDATED"
echo ""

# Initialize validation counters
TOTAL_CHECKS=0
PASSED_CHECKS=0

# Validation Check 1: Schema Validation
echo "Check 1: Schema Validation"
REQUIRED_FIELDS=("run_id" "spec_path" "output_dir" "status" "completed_iterations" "iterations" "used_urls" "validation")
SCHEMA_VALID=true

for field in "${REQUIRED_FIELDS[@]}"; do
    if [ "$USE_JQ" = true ]; then
        if ! jq -e ".$field" "$STATE_FILE" > /dev/null 2>&1; then
            SCHEMA_VALID=false
            echo -e "${RED}  Missing field: $field${NC}"
        fi
    else
        if ! python3 -c "import json; d=json.load(open('$STATE_FILE')); assert '$field' in d" 2>/dev/null; then
            SCHEMA_VALID=false
            echo -e "${RED}  Missing field: $field${NC}"
        fi
    fi
done

TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ "$SCHEMA_VALID" = true ]; then
    echo -e "${GREEN}✓ PASS: All required fields present${NC}"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}✗ FAIL: Missing required fields${NC}"
fi
echo ""

# Validation Check 2: File Count
echo "Check 2: File Count"
if [ -d "$OUTPUT_DIR" ]; then
    FILE_COUNT=$(ls -1 "$OUTPUT_DIR" 2>/dev/null | wc -l)
    FILE_COUNT=$(echo $FILE_COUNT | tr -d ' ')

    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
    if [ $FILE_COUNT -ge $COMPLETED ]; then
        echo -e "${GREEN}✓ PASS: File count matches${NC}"
        echo "  Expected: >=$COMPLETED, Actual: $FILE_COUNT"
        PASSED_CHECKS=$((PASSED_CHECKS + 1))
    else
        echo -e "${RED}✗ FAIL: File count mismatch${NC}"
        echo "  Expected: >=$COMPLETED, Actual: $FILE_COUNT"
    fi
else
    TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
    echo -e "${RED}✗ FAIL: Output directory does not exist${NC}"
    echo "  Directory: $OUTPUT_DIR"
fi
echo ""

# Validation Check 3: Iteration Records
echo "Check 3: Iteration Records Consistency"
if [ "$USE_JQ" = true ]; then
    ITERATION_COUNT=$(jq '[.iterations[] | select(.status == "completed")] | length' "$STATE_FILE")
else
    ITERATION_COUNT=$(python3 -c "import json; d=json.load(open('$STATE_FILE')); print(len([i for i in d['iterations'] if i['status'] == 'completed']))")
fi

TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ $ITERATION_COUNT -eq $COMPLETED ]; then
    echo -e "${GREEN}✓ PASS: Iteration records match${NC}"
    echo "  Expected: $COMPLETED, Actual: $ITERATION_COUNT"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}✗ FAIL: Iteration records mismatch${NC}"
    echo "  Expected: $COMPLETED, Actual: $ITERATION_COUNT"
fi
echo ""

# Validation Check 4: URL Uniqueness
echo "Check 4: URL Uniqueness"
if [ "$USE_JQ" = true ]; then
    TOTAL_URLS=$(jq '.used_urls | length' "$STATE_FILE")
    UNIQUE_URLS=$(jq '.used_urls | unique | length' "$STATE_FILE")
else
    TOTAL_URLS=$(python3 -c "import json; print(len(json.load(open('$STATE_FILE'))['used_urls']))")
    UNIQUE_URLS=$(python3 -c "import json; print(len(set(json.load(open('$STATE_FILE'))['used_urls'])))")
fi

TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ $TOTAL_URLS -eq $UNIQUE_URLS ]; then
    echo -e "${GREEN}✓ PASS: All URLs are unique${NC}"
    echo "  Total: $TOTAL_URLS, Unique: $UNIQUE_URLS"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}✗ FAIL: Duplicate URLs found${NC}"
    echo "  Total: $TOTAL_URLS, Unique: $UNIQUE_URLS"
    echo "  Duplicates: $((TOTAL_URLS - UNIQUE_URLS))"
fi
echo ""

# Validation Check 5: File Existence
echo "Check 5: Output File Existence"
MISSING_FILES=0

if [ "$USE_JQ" = true ]; then
    # Extract completed iteration files
    jq -r '.iterations[] | select(.status == "completed") | .output_file' "$STATE_FILE" | while read -r file; do
        if [ ! -f "$file" ]; then
            echo -e "${YELLOW}  Missing: $file${NC}"
            MISSING_FILES=$((MISSING_FILES + 1))
        fi
    done
else
    python3 -c "
import json
state = json.load(open('$STATE_FILE'))
missing = 0
for iteration in state['iterations']:
    if iteration['status'] == 'completed':
        import os
        if not os.path.exists(iteration['output_file']):
            print(f\"  Missing: {iteration['output_file']}\")
            missing += 1
exit(missing)
"
    MISSING_FILES=$?
fi

TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ $MISSING_FILES -eq 0 ]; then
    echo -e "${GREEN}✓ PASS: All output files exist${NC}"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}✗ FAIL: Some output files missing${NC}"
    echo "  Missing files: $MISSING_FILES"
fi
echo ""

# Validation Check 6: Timestamp Validity
echo "Check 6: Timestamp Chronology"
# Compare created vs updated timestamps
TIMESTAMP_VALID=true

# Use python for timestamp comparison
python3 -c "
from datetime import datetime
import json

state = json.load(open('$STATE_FILE'))
try:
    created = datetime.fromisoformat(state['created_at'].replace('Z', '+00:00'))
    updated = datetime.fromisoformat(state['updated_at'].replace('Z', '+00:00'))
    if updated < created:
        print('  ERROR: Updated timestamp before created timestamp')
        exit(1)
except Exception as e:
    print(f'  ERROR: Invalid timestamp format: {e}')
    exit(1)
" 2>&1

TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ $? -eq 0 ]; then
    echo -e "${GREEN}✓ PASS: Timestamps are valid${NC}"
    PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
    echo -e "${RED}✗ FAIL: Timestamp issues detected${NC}"
fi
echo ""

# Calculate consistency score (self-consistency via majority voting)
echo "=========================================="
echo "CONSISTENCY SCORE (SELF-CONSISTENCY)"
echo "=========================================="
echo ""

CONSISTENCY_SCORE=$(python3 -c "print(f'{$PASSED_CHECKS / $TOTAL_CHECKS:.2f}')")
CONSISTENCY_PCT=$(python3 -c "print(f'{($PASSED_CHECKS / $TOTAL_CHECKS) * 100:.0f}')")

echo "Passed Checks: $PASSED_CHECKS / $TOTAL_CHECKS"
echo "Consistency Score: $CONSISTENCY_SCORE ($CONSISTENCY_PCT%)"
echo ""

# Determine status and recommendations
if (( $(echo "$CONSISTENCY_SCORE >= 0.8" | bc -l) )); then
    echo -e "${GREEN}STATUS: CONSISTENT${NC}"
    echo "State is reliable and can be used safely."
    echo ""
    echo "Actions:"
    echo "  - Safe to resume with: /resume $RUN_ID"
    echo "  - No state repairs needed"
elif (( $(echo "$CONSISTENCY_SCORE >= 0.5" | bc -l) )); then
    echo -e "${YELLOW}STATUS: WARNING${NC}"
    echo "State has some inconsistencies but may be recoverable."
    echo ""
    echo "Actions:"
    echo "  - Review failed checks above"
    echo "  - Consider: /reset-state $RUN_ID --rebuild"
    echo "  - Manual inspection recommended"
else
    echo -e "${RED}STATUS: CORRUPTED${NC}"
    echo "State has significant issues and may be unreliable."
    echo ""
    echo "Actions:"
    echo "  - Rebuild state: /reset-state $RUN_ID --rebuild"
    echo "  - Or start new run"
    echo "  - Manual repair may be needed"
fi

echo ""
echo "=========================================="

# Exit code based on consistency
if (( $(echo "$CONSISTENCY_SCORE >= 0.8" | bc -l) )); then
    exit 0
else
    exit 1
fi
