<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Distributed\Scheduler\Validation;

use PpPhp\Core\Platform\Event\Distributed\DistributedRuntimeCoordinator;
use PpPhp\Core\Platform\Event\Distributed\Lease\DistributedLeaseManager;
use PpPhp\Core\Platform\Event\Distributed\Queue\DistributedQueueCoordinator;
use PpPhp\Core\Platform\Event\Distributed\Scheduler\DistributedScheduleJob;
use PpPhp\Core\Platform\Event\Distributed\Scheduler\DistributedScheduler;

final class DistributedSchedulerVerifier
{
    public function verify(string $basePath): array
    {
        $runtime = DistributedRuntimeCoordinator::resetInstance($basePath);
        $runtime->clear();
        $runtime->registerWorker('scheduler_worker_high', 'scheduler_node_a', 3);
        $runtime->registerWorker('scheduler_worker_low', 'scheduler_node_b', 1);

        $leases = DistributedLeaseManager::resetInstance($basePath);
        $leases->clear();

        $queues = DistributedQueueCoordinator::resetInstance($basePath);
        $queues->clear();
        $queues->registerQueue('scheduler.default', 10);
        $queues->registerQueue('scheduler.low', 1);
        $queues->updateCounters('scheduler.default', 20, 0);
        $queues->updateCounters('scheduler.low', 2, 0);

        $scheduler = DistributedScheduler::resetInstance($basePath);
        $scheduler->clear();

        $job = DistributedScheduleJob::create('scheduler_job_1', 'scheduler.default', 10);
        $assignment = $scheduler->schedule($job);

        $affinityJob = DistributedScheduleJob::create('scheduler_job_2', 'scheduler.default', 10, ['nodeId' => 'scheduler_node_b']);
        $affinityAssignment = $scheduler->schedule($affinityJob);

        $balance = $scheduler->rebalance();
        $scheduler->save();

        $second = DistributedScheduler::resetInstance($basePath);
        $second->hydrate();
        $summary = $second->summary();
        $stats = $summary['statistics'];

        $checks = [
            'assignment' => $assignment->isAssigned(),
            'affinity' => $affinityAssignment->isAssigned(),
            'leases' => DistributedLeaseManager::instance($basePath)->collection()->count() >= 2,
            'rebalance' => ($balance['balanced'] ?? false) === true,
            'persistence' => $second->store()->exists(),
            'hydration' => ($stats['assignments'] ?? 0) === 2,
        ];

        $issues = [];
        foreach ($checks as $check => $ok) {
            if (!$ok) {
                $issues[] = ['check' => $check, 'message' => 'Distributed scheduler verification failed: ' . $check];
            }
        }

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'assignments' => $stats['assignments'] ?? 0,
                'assigned' => $stats['assigned'] ?? 0,
                'failed' => $stats['failed'] ?? 0,
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
