<?php

declare(strict_types=1);

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

use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos\ComponentVulnerabilitiesDto;
use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos\InstalledComponentDto;

/**
 * Strategy contract for synchronizing vulnerability data for a specific component type.
 *
 * In Strategy terms: this interface defines *how* vulnerability data is synchronized
 * for a given component type (enumeration, fetching, and mapping). Multiple concrete
 * implementations are interchangeable and selected by a coordinating service based
 * on the component type.
 *
 * This is explicitly not a Policy. Implementations do not decide *whether* or *when*
 * a synchronization should occur, nor do they make notification or severity decisions.
 * Those concerns are handled by higher-level orchestration or policy components.
 *
 * A component can be a plugin, theme, or WordPress core. Each implementation of this
 * interface is responsible for handling exactly one component type.
 *
 * The typical lifecycle for a sync strategy is:
 * 1. Enumerate installed components of its type.
 * 2. Fetch remote vulnerability data for each installed component.
 * 3. Map the API response into a ComponentVulnerabilitiesDto for storage.
 */
interface ComponentSyncStrategyInterface
{
    /**
     * Return the component type handled by this strategy.
     *
     * This value is used to:
     * - Route API calls to the correct endpoint.
     * - Tag stored vulnerability data with the correct component type.
     * - Produce meaningful error and log messages.
     *
     * Examples: "plugin", "theme", "core".
     *
     * @return non-empty-string
     */
    public function getType(): string;

    /**
     * Retrieve all installed components of the handled type.
     *
     * Each returned InstalledComponentDto represents a single installed
     * component (for example, one plugin or one theme) including runtime
     * information such as slug, name, and installed version.
     *
     * @return iterable<InstalledComponentDto>
     */
    public function getInstalledComponents(): iterable;

    /**
     * Fetch raw vulnerability data for a single installed component.
     *
     * Implementations are expected to:
     * - Extract the component identifier (such as slug and name).
     * - Call the appropriate remote vulnerability API.
     * - Return a standardized success/error payload that the sync service
     *   can process consistently.
     *
     * @return array{success: bool, data?: array<string, mixed>, message?: string}
     */
    public function fetchComponent(InstalledComponentDto $installedComponentDto): array;

    /**
     * Convert a raw API payload into a ComponentVulnerabilitiesDto.
     *
     * This method maps external API data to the internal storage format and
     * enriches it with runtime information from the installed component
     * (such as slug, name, installed version, and update availability).
     *
     * @param array<string, mixed> $apiPayload Raw vulnerability API response.
     */
    public function toComponentDto(array $apiPayload, InstalledComponentDto $installedComponentDto): ComponentVulnerabilitiesDto;
}
