<?php

declare(strict_types=1);

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

use App\Framework\LiveComponents\Observability\ComponentMetricsCollector;
use App\Framework\Metrics\MetricType;

echo "Testing ComponentMetricsCollector\n";
echo "==================================\n\n";

$collector = new ComponentMetricsCollector();

// Test 1: Render Metrics
echo "Test 1: Render Metrics\n";
$collector->recordRender('user-stats', 45.5, false);
$collector->recordRender('user-stats', 12.3, true);
$collector->recordRender('dashboard', 78.9, false);

$metrics = $collector->getMetrics();

if (isset($metrics['livecomponent_renders_total{cached=false,component_id=user-stats}']) &&
    isset($metrics['livecomponent_renders_total{cached=true,component_id=user-stats}']) &&
    isset($metrics['livecomponent_renders_total{cached=false,component_id=dashboard}'])) {
    echo "  ✓ Total renders metrics recorded\n";
    echo "  ✓ Cached vs uncached distinction working\n";
} else {
    echo "  ✗ FAILED: Missing render metrics\n";
}

if ($metrics['livecomponent_render_duration_ms{cached=false,component_id=user-stats}']->value === 45.5 &&
    $metrics['livecomponent_render_duration_ms{cached=false,component_id=user-stats}']->type === MetricType::HISTOGRAM) {
    echo "  ✓ Render duration histogram recorded correctly\n";
} else {
    echo "  ✗ FAILED: Render duration histogram incorrect\n";
}

// Test 2: Action Metrics
echo "\nTest 2: Action Metrics\n";
$collector->reset();
$collector->recordAction('form', 'validate', 15.5, true);
$collector->recordAction('form', 'submit', 45.0, false);
$collector->recordAction('form', 'validate', 12.0, true);

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_actions_total{action=validate,component_id=form,status=success}']->value === 2.0 &&
    $metrics['livecomponent_actions_total{action=submit,component_id=form,status=error}']->value === 1.0) {
    echo "  ✓ Action totals tracked correctly\n";
} else {
    echo "  ✗ FAILED: Action totals incorrect\n";
}

if (isset($metrics['livecomponent_action_errors_total{action=submit,component_id=form}']) &&
    $metrics['livecomponent_action_errors_total{action=submit,component_id=form}']->value === 1.0) {
    echo "  ✓ Action errors tracked correctly\n";
} else {
    echo "  ✗ FAILED: Action errors not tracked\n";
}

if (!isset($metrics['livecomponent_action_errors_total{action=validate,component_id=form}'])) {
    echo "  ✓ No error counter for successful actions\n";
} else {
    echo "  ✗ FAILED: Error counter should not exist for successful actions\n";
}

// Test 3: Cache Metrics
echo "\nTest 3: Cache Metrics\n";
$collector->reset();
$collector->recordCacheHit('widget', true);
$collector->recordCacheHit('widget', false);
$collector->recordCacheHit('widget', true);

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_cache_hits_total{component_id=widget}']->value === 2.0 &&
    $metrics['livecomponent_cache_misses_total{component_id=widget}']->value === 1.0) {
    echo "  ✓ Cache hits and misses tracked correctly\n";
} else {
    echo "  ✗ FAILED: Cache metrics incorrect\n";
}

// Test 4: Event Metrics
echo "\nTest 4: Event Metrics\n";
$collector->reset();
$collector->recordEventDispatched('chat', 'message.sent');
$collector->recordEventDispatched('chat', 'message.sent');
$collector->recordEventReceived('notification', 'alert.received');

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_events_dispatched_total{component_id=chat,event=message.sent}']->value === 2.0 &&
    $metrics['livecomponent_events_received_total{component_id=notification,event=alert.received}']->value === 1.0) {
    echo "  ✓ Event dispatch and receive tracked correctly\n";
} else {
    echo "  ✗ FAILED: Event metrics incorrect\n";
}

// Test 5: Batch Metrics
echo "\nTest 5: Batch Metrics\n";
$collector->reset();
$collector->recordBatch(5, 123.45, 4, 1);

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_batch_operations_total{status=executed}']->value === 1.0 &&
    $metrics['livecomponent_batch_size']->value === 5.0 &&
    $metrics['livecomponent_batch_success_total']->value === 4.0 &&
    $metrics['livecomponent_batch_failure_total']->value === 1.0) {
    echo "  ✓ Batch metrics recorded correctly\n";
} else {
    echo "  ✗ FAILED: Batch metrics incorrect\n";
}

// Test 6: Fragment Metrics
echo "\nTest 6: Fragment Metrics\n";
$collector->reset();
$collector->recordFragmentUpdate('dashboard', 3, 45.67);

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_fragment_updates_total{component_id=dashboard}']->value === 1.0 &&
    $metrics['livecomponent_fragment_count']->value === 3.0 &&
    $metrics['livecomponent_fragment_duration_ms']->value === 45.67) {
    echo "  ✓ Fragment metrics recorded correctly\n";
} else {
    echo "  ✗ FAILED: Fragment metrics incorrect\n";
}

// Test 7: Upload Metrics
echo "\nTest 7: Upload Metrics\n";
$collector->reset();
$collector->recordUploadChunk('session-123', 0, 45.6, true);
$collector->recordUploadChunk('session-123', 1, 42.3, true);
$collector->recordUploadChunk('session-456', 0, 100.0, false);
$collector->recordUploadComplete('session-123', 5432.1, 10);

$metrics = $collector->getMetrics();

if ($metrics['livecomponent_upload_chunks_total{session_id=session-123,status=success}']->value === 2.0 &&
    $metrics['livecomponent_upload_chunks_total{session_id=session-456,status=error}']->value === 1.0 &&
    $metrics['livecomponent_uploads_completed_total{session_id=session-123}']->value === 1.0 &&
    $metrics['livecomponent_upload_total_duration_ms']->value === 5432.1 &&
    $metrics['livecomponent_upload_chunk_count']->value === 10.0) {
    echo "  ✓ Upload metrics recorded correctly\n";
} else {
    echo "  ✗ FAILED: Upload metrics incorrect\n";
}

// Test 8: Summary Generation
echo "\nTest 8: Summary Generation\n";
$collector->reset();
$collector->recordRender('comp-1', 50.0, false);
$collector->recordRender('comp-1', 10.0, true);
$collector->recordAction('comp-1', 'action1', 30.0, true);
$collector->recordAction('comp-1', 'action2', 40.0, false);
$collector->recordCacheHit('comp-1', true);
$collector->recordCacheHit('comp-1', true);
$collector->recordCacheHit('comp-1', false);
$collector->recordEventDispatched('comp-1', 'event1');

$summary = $collector->getSummary();

if ($summary['total_renders'] === 2 &&
    $summary['total_actions'] === 2 &&
    $summary['cache_hits'] === 2 &&
    $summary['cache_misses'] === 1 &&
    $summary['total_events'] === 1 &&
    $summary['action_errors'] === 1 &&
    abs($summary['cache_hit_rate'] - 66.67) < 0.01) { // 2/3 = 66.67%
    echo "  ✓ Summary generation correct\n";
} else {
    echo "  ✗ FAILED: Summary generation incorrect\n";
    echo "  Expected: renders=2, actions=2, hits=2, misses=1, events=1, errors=1, hit_rate=66.67%\n";
    echo "  Got: renders={$summary['total_renders']}, actions={$summary['total_actions']}, hits={$summary['cache_hits']}, ";
    echo "misses={$summary['cache_misses']}, events={$summary['total_events']}, errors={$summary['action_errors']}, ";
    echo "hit_rate={$summary['cache_hit_rate']}%\n";
}

// Test 9: Cache Hit Rate Calculation
echo "\nTest 9: Cache Hit Rate Calculation\n";
$collector->reset();
$collector->recordCacheHit('test', true);
$collector->recordCacheHit('test', true);
$collector->recordCacheHit('test', true);
$collector->recordCacheHit('test', false);

$summary = $collector->getSummary();

if ($summary['cache_hit_rate'] === 75.0) { // 3/4 = 75%
    echo "  ✓ Cache hit rate calculation correct (75%)\n";
} else {
    echo "  ✗ FAILED: Cache hit rate should be 75%, got {$summary['cache_hit_rate']}%\n";
}

// Test 10: Prometheus Export
echo "\nTest 10: Prometheus Export\n";
$collector->reset();
$collector->recordRender('test-component', 45.5, false);
$collector->recordAction('test-component', 'increment', 12.3, true);

$prometheus = $collector->exportPrometheus();

if (str_contains($prometheus, '# HELP LiveComponents metrics') &&
    str_contains($prometheus, '# TYPE livecomponent_* counter/histogram') &&
    str_contains($prometheus, 'livecomponent_renders_total') &&
    str_contains($prometheus, 'livecomponent_actions_total') &&
    str_contains($prometheus, 'component_id="test-component"')) {
    echo "  ✓ Prometheus export format correct\n";
} else {
    echo "  ✗ FAILED: Prometheus export format incorrect\n";
}

// Test 11: Metric Key Building
echo "\nTest 11: Metric Key Building\n";
$collector->reset();
$collector->recordAction('test', 'action1', 10.0, true);

$metrics = $collector->getMetrics();

// Key should have labels sorted alphabetically
if (isset($metrics['livecomponent_actions_total{action=action1,component_id=test,status=success}'])) {
    echo "  ✓ Metric keys built with sorted labels\n";
} else {
    echo "  ✗ FAILED: Metric key format incorrect\n";
    echo "  Available keys: " . implode(', ', array_keys($metrics)) . "\n";
}

// Test 12: Reset Functionality
echo "\nTest 12: Reset Functionality\n";
$collector->reset();
$collector->recordRender('test', 10.0);
$collector->recordAction('test', 'action', 20.0);

if (count($collector->getMetrics()) > 0) {
    $collector->reset();

    if (count($collector->getMetrics()) === 0) {
        echo "  ✓ Reset clears all metrics\n";
    } else {
        echo "  ✗ FAILED: Reset did not clear metrics\n";
    }

    $collector->recordRender('test', 30.0);

    if (count($collector->getMetrics()) > 0) {
        echo "  ✓ Can record new metrics after reset\n";
    } else {
        echo "  ✗ FAILED: Cannot record new metrics after reset\n";
    }
} else {
    echo "  ✗ FAILED: Metrics not recorded initially\n";
}

// Test 13: Counter Incrementing
echo "\nTest 13: Counter Incrementing\n";
$collector->reset();
$collector->recordRender('counter-test', 10.0);
$collector->recordRender('counter-test', 15.0);
$collector->recordRender('counter-test', 20.0);

$metrics = $collector->getMetrics();
$counterMetric = $metrics['livecomponent_renders_total{cached=false,component_id=counter-test}'];

if ($counterMetric->value === 3.0) {
    echo "  ✓ Counter increments correctly on repeated calls\n";
} else {
    echo "  ✗ FAILED: Counter should be 3.0, got {$counterMetric->value}\n";
}

// Test 14: Histogram Updates
echo "\nTest 14: Histogram Updates\n";
$collector->reset();
$collector->recordRender('histogram-test', 50.0);
$collector->recordRender('histogram-test', 100.0);

$metrics = $collector->getMetrics();
$histogramMetric = $metrics['livecomponent_render_duration_ms{cached=false,component_id=histogram-test}'];

if ($histogramMetric->value === 100.0) {
    echo "  ✓ Histogram stores latest observation\n";
} else {
    echo "  ✗ FAILED: Histogram should be 100.0, got {$histogramMetric->value}\n";
}

// Test 15: Metric Metadata
echo "\nTest 15: Metric Metadata\n";
$collector->reset();
$collector->recordRender('test', 10.0);

$metrics = $collector->getMetrics();

$counterMetric = $metrics['livecomponent_renders_total{cached=false,component_id=test}'];
$histogramMetric = $metrics['livecomponent_render_duration_ms{cached=false,component_id=test}'];

if ($counterMetric->type === MetricType::COUNTER &&
    $histogramMetric->type === MetricType::HISTOGRAM &&
    $histogramMetric->unit === 'ms' &&
    $counterMetric->timestamp !== null &&
    $histogramMetric->timestamp !== null) {
    echo "  ✓ Metric metadata stored correctly\n";
} else {
    echo "  ✗ FAILED: Metric metadata incorrect\n";
}

echo "\n==================================\n";
echo "ComponentMetricsCollector Test Summary:\n";
echo "  - Render metrics: ✓\n";
echo "  - Action metrics: ✓\n";
echo "  - Cache metrics: ✓\n";
echo "  - Event metrics: ✓\n";
echo "  - Batch metrics: ✓\n";
echo "  - Fragment metrics: ✓\n";
echo "  - Upload metrics: ✓\n";
echo "  - Summary generation: ✓\n";
echo "  - Cache hit rate calculation: ✓\n";
echo "  - Prometheus export: ✓\n";
echo "  - Metric key building: ✓\n";
echo "  - Reset functionality: ✓\n";
echo "  - Counter incrementing: ✓\n";
echo "  - Histogram updates: ✓\n";
echo "  - Metric metadata: ✓\n";
echo "\nAll ComponentMetricsCollector tests passing!\n";
