<?php

namespace App\Service;

final class LockService
{
    private $handle = null;
    private string $lockFile;

    public function __construct(string $projectDir)
    {
        $dir = $projectDir . '/var/locks';
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }

        $this->lockFile = $dir . '/ingest.lock';
    }

    /**
     * Gibt true zurück, wenn Lock erfolgreich gesetzt wurde.
     * Wenn false: ein anderer Prozess hält den Lock.
     */
    public function acquire(): bool
    {
        $handle = fopen($this->lockFile, 'c+');
        if (!$handle) {
            throw new \RuntimeException('Could not open lock file.');
        }

        // Nicht-blockierend: sofort true/false
        if (!flock($handle, LOCK_EX | LOCK_NB)) {
            fclose($handle);
            return false;
        }

        // Lock halten: Handle offen lassen
        $this->handle = $handle;

        // Optional: Metainfo reinschreiben
        ftruncate($this->handle, 0);
        fwrite($this->handle, (string) time());

        return true;
    }

    public function release(): void
    {
        if ($this->handle) {
            flock($this->handle, LOCK_UN);
            fclose($this->handle);
            $this->handle = null;
        }
    }

    public function isLocked(): bool
    {
        $handle = fopen($this->lockFile, 'c+');
        if (!$handle) {
            return false;
        }

        $locked = !flock($handle, LOCK_EX | LOCK_NB);
        if (!$locked) {
            flock($handle, LOCK_UN);
        }
        fclose($handle);

        return $locked;
    }
}
