<?php

declare(strict_types=1);

namespace PhpWA\Integration;

use InvalidArgumentException;
use PhpWA\Exception\RunCancelledException;
use PhpWA\Runtime\RunCheckpoint;
use PhpWA\Runtime\RunGuardInterface;





final class GenerationRunGuard implements RunGuardInterface
{
      private $expectedGeneration;
      private $generationReader;
      private $heartbeat;

    



    public function __construct(int $expectedGeneration, callable $generationReader, ?callable $heartbeat = null)
    {
        if ($expectedGeneration < 1) {
            throw new InvalidArgumentException('Expected run generation must be positive.');
        }
        $this->expectedGeneration = $expectedGeneration;
        $this->generationReader = $generationReader;
        $this->heartbeat = $heartbeat;
    }

    public function check(RunCheckpoint $checkpoint): void
    {
        $current = ($this->generationReader)();
        if (!is_int($current) || $current < 1) {
            throw new InvalidArgumentException('Run generation reader must return a positive integer.');
        }
        if ($current !== $this->expectedGeneration) {
            throw new RunCancelledException('PhpWA worker was superseded by a newer application generation.');
        }
        if ($this->heartbeat !== null) {
            ($this->heartbeat)($checkpoint);
        }
    }
}
