<?php

declare(strict_types=1);

namespace App\Support\Baselines;

use InvalidArgumentException;

final class SupportCapabilityRecord
{
    /**
     * @param  non-empty-string  $policyType
     * @param  'supported'|'limited'|'unsupported'  $compareCapability
     * @param  'supported'|'limited'|'unsupported'  $captureCapability
     * @param  'policy'|'inventory'|'derived'|null  $sourceModelExpected
     */
    public function __construct(
        public readonly string $policyType,
        public readonly SubjectClass $subjectClass,
        public readonly string $compareCapability,
        public readonly string $captureCapability,
        public readonly ResolutionPath $resolutionPath,
        public readonly bool $configSupported,
        public readonly bool $runtimeValid,
        public readonly ?string $sourceModelExpected = null,
    ) {}

    /**
     * @return 'supported'|'limited'|'excluded'|'invalid_support_config'
     */
    public function supportModeFor(string $operation): string
    {
        $capability = match ($operation) {
            'compare' => $this->compareCapability,
            'capture' => $this->captureCapability,
            default => throw new InvalidArgumentException('Unsupported operation ['.$operation.'].'),
        };

        if ($this->configSupported && ! $this->runtimeValid) {
            return 'invalid_support_config';
        }

        return match ($capability) {
            'supported', 'limited' => $capability,
            default => 'excluded',
        };
    }

    public function allows(string $operation): bool
    {
        return in_array($this->supportModeFor($operation), ['supported', 'limited'], true);
    }

    public function toArray(): array
    {
        return [
            'policy_type' => $this->policyType,
            'subject_class' => $this->subjectClass->value,
            'compare_capability' => $this->compareCapability,
            'capture_capability' => $this->captureCapability,
            'resolution_path' => $this->resolutionPath->value,
            'config_supported' => $this->configSupported,
            'runtime_valid' => $this->runtimeValid,
            'source_model_expected' => $this->sourceModelExpected,
        ];
    }
}
