<?php

declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\DI\DefaultContainer;
use App\Framework\GraphQL\Attributes\GraphQLField;
use App\Framework\GraphQL\Attributes\GraphQLQuery;
use App\Framework\GraphQL\Execution\QueryParser;
use App\Framework\GraphQL\Schema\SchemaBuilder;
use App\Framework\GraphQL\Schema\TypeResolver;
use App\Framework\GraphQL\Validation\ComplexityAnalyzer;

echo "Testing GraphQL Complexity Analysis...\n\n";

// Setup
$container = new DefaultContainer();
$typeResolver = new TypeResolver();
$schemaBuilder = new SchemaBuilder($container, $typeResolver);

// Test Query Class
#[GraphQLQuery]
final readonly class ComplexityTestQueries
{
    #[GraphQLField(description: 'Simple query')]
    public function simple(): string
    {
        return 'simple';
    }

    #[GraphQLField(description: 'List query')]
    public function users(): array
    {
        return [];
    }

    #[GraphQLField(description: 'Nested query')]
    public function posts(): array
    {
        return [];
    }
}

$schema = $schemaBuilder->build([ComplexityTestQueries::class]);
$parser = new QueryParser();

// Test 1: Simple query (should pass)
echo "1. Testing Simple Query (should pass)...\n";
$simpleQuery = '{ simple }';
$parsed = $parser->parse($simpleQuery);

$analyzer = new ComplexityAnalyzer($schema, maxComplexity: 100, maxDepth: 5);
$score = $analyzer->analyze($parsed);

echo "   ✓ Complexity: {$score->totalComplexity}\n";
echo "   ✓ Depth: {$score->maxDepth}\n";
echo "   ✓ Field Count: {$score->fieldCount}\n\n";

// Test 2: List query (higher complexity)
echo "2. Testing List Query (higher complexity)...\n";
$listQuery = '{ users }';
$parsed = $parser->parse($listQuery);

$score = $analyzer->analyze($parsed);
echo "   ✓ Complexity: {$score->totalComplexity} (list multiplier applied)\n";
echo "   ✓ Depth: {$score->maxDepth}\n\n";

// Test 3: Nested query (depth penalty)
echo "3. Testing Nested Query (depth penalty)...\n";
$nestedQuery = <<<'GRAPHQL'
{
    posts {
        id
        title
        author {
            id
            name
            posts {
                id
                title
            }
        }
    }
}
GRAPHQL;

$parsed = $parser->parse($nestedQuery);
$score = $analyzer->analyze($parsed);

echo "   ✓ Complexity: {$score->totalComplexity} (depth penalty applied)\n";
echo "   ✓ Max Depth: {$score->maxDepth}\n";
echo "   ✓ Field Count: {$score->fieldCount}\n\n";

// Test 4: Overly complex query (should fail)
echo "4. Testing Overly Complex Query (should fail)...\n";

try {
    // Create a very strict analyzer
    $strictAnalyzer = new ComplexityAnalyzer($schema, maxComplexity: 50, maxDepth: 3);
    $strictAnalyzer->analyze($parsed);

    echo "   ❌ FAILED: Should have thrown exception\n";
} catch (\Exception $e) {
    echo "   ✓ Correctly rejected: " . $e->getMessage() . "\n";
}
echo "\n";

// Test 5: Too deep query (should fail)
echo "5. Testing Too Deep Query (should fail)...\n";

try {
    $deepQuery = <<<'GRAPHQL'
    {
        posts {
            author {
                posts {
                    author {
                        posts {
                            author {
                                id
                            }
                        }
                    }
                }
            }
        }
    }
    GRAPHQL;

    $parsed = $parser->parse($deepQuery);
    $depthAnalyzer = new ComplexityAnalyzer($schema, maxComplexity: 10000, maxDepth: 3);
    $depthAnalyzer->analyze($parsed);

    echo "   ❌ FAILED: Should have thrown exception\n";
} catch (\Exception $e) {
    echo "   ✓ Correctly rejected: " . $e->getMessage() . "\n";
}
echo "\n";

echo "✅ All Complexity Analysis Tests Passed!\n";
