<?php

declare(strict_types=1);

namespace App\Services\Baselines\Evidence;

use Carbon\CarbonImmutable;

final class EvidenceProvenance
{
    public const string FidelityContent = 'content';

    public const string FidelityMeta = 'meta';

    public const string SourcePolicyVersion = 'policy_version';

    public const string SourceInventory = 'inventory';

    public const string KeyFidelity = 'fidelity';

    public const string KeySource = 'source';

    public const string KeyObservedAt = 'observed_at';

    public const string KeyObservedOperationRunId = 'observed_operation_run_id';

    /**
     * @return array{
     *   fidelity: string,
     *   source: string,
     *   observed_at: ?string,
     *   observed_operation_run_id: ?int
     * }
     */
    public static function build(
        string $fidelity,
        string $source,
        ?CarbonImmutable $observedAt,
        ?int $observedOperationRunId,
    ): array {
        return [
            self::KeyFidelity => $fidelity,
            self::KeySource => $source,
            self::KeyObservedAt => $observedAt?->toIso8601String(),
            self::KeyObservedOperationRunId => $observedOperationRunId,
        ];
    }

    public static function weakerFidelity(string $baselineFidelity, string $currentFidelity): string
    {
        $baselineFidelity = strtolower(trim($baselineFidelity));
        $currentFidelity = strtolower(trim($currentFidelity));

        if ($baselineFidelity === self::FidelityMeta || $currentFidelity === self::FidelityMeta) {
            return self::FidelityMeta;
        }

        return self::FidelityContent;
    }

    public static function isValidFidelity(?string $fidelity): bool
    {
        return in_array($fidelity, [self::FidelityContent, self::FidelityMeta], true);
    }

    public static function isValidSource(?string $source): bool
    {
        return in_array($source, [self::SourcePolicyVersion, self::SourceInventory], true);
    }
}
