<?php

declare(strict_types=1);

namespace ReallySimplePlugins\RSS\Core\Features\Vulnerability\Repositories;

use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos\VulnerabilitySnapshotDto;

/**
 * Persists and reads the latest vulnerability snapshot from WordPress option storage.
 *
 * Constraints: No external I/O and no business rules beyond basic shape validation.
 */
final class VulnerabilitySnapshotRepository
{
    private const OPTION_KEY = 'rsssl_vulnerability_snapshot';

    public function getLatest(): ?VulnerabilitySnapshotDto
    {
        $raw = get_option(self::OPTION_KEY, null);
        if (!is_array($raw)) {
            return null;
        }

        return VulnerabilitySnapshotDto::fromArray($raw);
    }

    public function storeLatest(VulnerabilitySnapshotDto $vulnerabilitySnapshotDto): void
    {
        $this->save($vulnerabilitySnapshotDto);
    }

    public function save(VulnerabilitySnapshotDto $vulnerabilitySnapshotDto): void
    {
        update_option(self::OPTION_KEY, $vulnerabilitySnapshotDto->toArray(), false);
    }

    public function clear(): void
    {
        delete_option(self::OPTION_KEY);
    }

    /**
     * Builds a snapshot from the repository's aggregated snapshot data.
     */
    public function buildCurrentSnapshot(VulnerabilityStorageRepository $vulnerabilityStorageRepository): VulnerabilitySnapshotDto
    {
        $data = $vulnerabilityStorageRepository->getSnapshotData();

        $updatableComponents = (int)($data['updatableComponents'] ?? 0);
        $vulnerableCount = (int)($data['vulnerablePlugins'] ?? 0);
        $highestSeverity = isset($data['highestSeverity']) && is_string($data['highestSeverity'])
            ? $data['highestSeverity']
            : null;
        $severityScore = (int)($data['severityScore'] ?? 0);

        return new VulnerabilitySnapshotDto(
            $highestSeverity,
            $severityScore,
            $vulnerableCount,
            $updatableComponents,
            time()
        );
    }

    public function buildFromStorage(
        VulnerabilityStorageRepository $vulnerabilityStorageRepository
    ): VulnerabilitySnapshotDto {
        return $this->buildCurrentSnapshot($vulnerabilityStorageRepository);
    }
}
