<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Sourcing\Verification;

final class EventSourcingRuntimeStore
{
    public const REPORT_FILE = 'storage/reports/r0100/r0100-event-sourcing-cqrs-runtime-report.json';
    public const LOCK_FILE = 'storage/reports/r0100/r0100-event-sourcing-cqrs-runtime-lock.json';

    public function __construct(
        private readonly string $basePath,
        private readonly EventSourcingRuntimeSerializer $serializer = new EventSourcingRuntimeSerializer()
    ) {}

    public function reportFile(): string
    {
        return rtrim($this->basePath, DIRECTORY_SEPARATOR) . '/' . self::REPORT_FILE;
    }

    public function lockFile(): string
    {
        return rtrim($this->basePath, DIRECTORY_SEPARATOR) . '/' . self::LOCK_FILE;
    }

    public function saveReport(EventSourcingRuntimeReport $report): EventSourcingRuntimeReport
    {
        $file = $this->reportFile();

        if (!is_dir(dirname($file))) {
            mkdir(dirname($file), 0775, true);
        }

        file_put_contents($file, $this->serializer->encode($report->toArray()));
        return $report;
    }

    public function saveLock(EventSourcingRuntimeLock $lock): EventSourcingRuntimeLock
    {
        $file = $this->lockFile();

        if (!is_dir(dirname($file))) {
            mkdir(dirname($file), 0775, true);
        }

        file_put_contents($file, $this->serializer->encode($lock->toArray()));
        return $lock;
    }

    public function loadReport(): ?EventSourcingRuntimeReport
    {
        $file = $this->reportFile();
        if (!is_file($file)) {
            return null;
        }

        return EventSourcingRuntimeReport::fromArray($this->serializer->decode((string) file_get_contents($file)));
    }

    public function loadLock(): ?EventSourcingRuntimeLock
    {
        $file = $this->lockFile();
        if (!is_file($file)) {
            return null;
        }

        return EventSourcingRuntimeLock::fromArray($this->serializer->decode((string) file_get_contents($file)));
    }

    public function reportExists(): bool { return is_file($this->reportFile()); }
    public function lockExists(): bool { return is_file($this->lockFile()); }
}
