<?php

declare(strict_types=1);

namespace App\Support\Baselines;

/**
 * Stable reason codes for 422 precondition failures.
 *
 * These codes are returned in the response body when a baseline operation
 * cannot start due to unmet preconditions. No OperationRun is created.
 */
final class BaselineReasonCodes
{
    public const string CAPTURE_MISSING_SOURCE_TENANT = 'baseline.capture.missing_source_tenant';

    public const string CAPTURE_PROFILE_NOT_ACTIVE = 'baseline.capture.profile_not_active';

    public const string CAPTURE_ROLLOUT_DISABLED = 'baseline.capture.rollout_disabled';

    public const string CAPTURE_INVALID_SCOPE = 'baseline.capture.invalid_scope';

    public const string CAPTURE_UNSUPPORTED_SCOPE = 'baseline.capture.unsupported_scope';

    public const string CAPTURE_INVENTORY_MISSING = 'baseline.capture.inventory_missing';

    public const string CAPTURE_INVENTORY_BLOCKED = 'baseline.capture.inventory_blocked';

    public const string CAPTURE_INVENTORY_FAILED = 'baseline.capture.inventory_failed';

    public const string CAPTURE_UNUSABLE_COVERAGE = 'baseline.capture.unusable_coverage';

    public const string CAPTURE_ZERO_SUBJECTS = 'baseline.capture.zero_subjects';

    public const string SNAPSHOT_BUILDING = 'baseline.snapshot.building';

    public const string SNAPSHOT_INCOMPLETE = 'baseline.snapshot.incomplete';

    public const string SNAPSHOT_SUPERSEDED = 'baseline.snapshot.superseded';

    public const string SNAPSHOT_CAPTURE_FAILED = 'baseline.snapshot.capture_failed';

    public const string SNAPSHOT_COMPLETION_PROOF_FAILED = 'baseline.snapshot.completion_proof_failed';

    public const string SNAPSHOT_LEGACY_NO_PROOF = 'baseline.snapshot.legacy_no_proof';

    public const string SNAPSHOT_LEGACY_CONTRADICTORY = 'baseline.snapshot.legacy_contradictory';

    public const string COMPARE_NO_ASSIGNMENT = 'baseline.compare.no_assignment';

    public const string COMPARE_PROFILE_NOT_ACTIVE = 'baseline.compare.profile_not_active';

    public const string COMPARE_NO_ACTIVE_SNAPSHOT = 'baseline.compare.no_active_snapshot';

    public const string COMPARE_NO_CONSUMABLE_SNAPSHOT = 'baseline.compare.no_consumable_snapshot';

    public const string COMPARE_NO_ELIGIBLE_TARGET = 'baseline.compare.no_eligible_target';

    public const string COMPARE_INVALID_SNAPSHOT = 'baseline.compare.invalid_snapshot';

    public const string COMPARE_ROLLOUT_DISABLED = 'baseline.compare.rollout_disabled';

    public const string COMPARE_INVALID_SCOPE = 'baseline.compare.invalid_scope';

    public const string COMPARE_UNSUPPORTED_SCOPE = 'baseline.compare.unsupported_scope';

    public const string COMPARE_MIXED_SCOPE = 'baseline.compare.mixed_scope';

    public const string COMPARE_SNAPSHOT_BUILDING = 'baseline.compare.snapshot_building';

    public const string COMPARE_SNAPSHOT_INCOMPLETE = 'baseline.compare.snapshot_incomplete';

    public const string COMPARE_SNAPSHOT_SUPERSEDED = 'baseline.compare.snapshot_superseded';

    /**
     * @return array<int, string>
     */
    public static function all(): array
    {
        return [
            self::CAPTURE_MISSING_SOURCE_TENANT,
            self::CAPTURE_PROFILE_NOT_ACTIVE,
            self::CAPTURE_ROLLOUT_DISABLED,
            self::CAPTURE_INVALID_SCOPE,
            self::CAPTURE_UNSUPPORTED_SCOPE,
            self::CAPTURE_INVENTORY_MISSING,
            self::CAPTURE_INVENTORY_BLOCKED,
            self::CAPTURE_INVENTORY_FAILED,
            self::CAPTURE_UNUSABLE_COVERAGE,
            self::CAPTURE_ZERO_SUBJECTS,
            self::SNAPSHOT_BUILDING,
            self::SNAPSHOT_INCOMPLETE,
            self::SNAPSHOT_SUPERSEDED,
            self::SNAPSHOT_CAPTURE_FAILED,
            self::SNAPSHOT_COMPLETION_PROOF_FAILED,
            self::SNAPSHOT_LEGACY_NO_PROOF,
            self::SNAPSHOT_LEGACY_CONTRADICTORY,
            self::COMPARE_NO_ASSIGNMENT,
            self::COMPARE_PROFILE_NOT_ACTIVE,
            self::COMPARE_NO_ACTIVE_SNAPSHOT,
            self::COMPARE_NO_CONSUMABLE_SNAPSHOT,
            self::COMPARE_NO_ELIGIBLE_TARGET,
            self::COMPARE_INVALID_SNAPSHOT,
            self::COMPARE_ROLLOUT_DISABLED,
            self::COMPARE_INVALID_SCOPE,
            self::COMPARE_UNSUPPORTED_SCOPE,
            self::COMPARE_MIXED_SCOPE,
            self::COMPARE_SNAPSHOT_BUILDING,
            self::COMPARE_SNAPSHOT_INCOMPLETE,
            self::COMPARE_SNAPSHOT_SUPERSEDED,
        ];
    }

    public static function isKnown(?string $reasonCode): bool
    {
        return is_string($reasonCode) && in_array(trim($reasonCode), self::all(), true);
    }

    public static function trustImpact(?string $reasonCode): ?string
    {
        return match (trim((string) $reasonCode)) {
            self::SNAPSHOT_CAPTURE_FAILED => 'limited_confidence',
            self::COMPARE_ROLLOUT_DISABLED,
            self::CAPTURE_ROLLOUT_DISABLED,
            self::SNAPSHOT_BUILDING,
            self::SNAPSHOT_INCOMPLETE,
            self::SNAPSHOT_SUPERSEDED,
            self::SNAPSHOT_COMPLETION_PROOF_FAILED,
            self::SNAPSHOT_LEGACY_NO_PROOF,
            self::SNAPSHOT_LEGACY_CONTRADICTORY,
            self::COMPARE_NO_ASSIGNMENT,
            self::COMPARE_PROFILE_NOT_ACTIVE,
            self::COMPARE_NO_ACTIVE_SNAPSHOT,
            self::COMPARE_NO_CONSUMABLE_SNAPSHOT,
            self::COMPARE_NO_ELIGIBLE_TARGET,
            self::COMPARE_INVALID_SNAPSHOT,
            self::COMPARE_SNAPSHOT_BUILDING,
            self::COMPARE_SNAPSHOT_INCOMPLETE,
            self::COMPARE_SNAPSHOT_SUPERSEDED,
            self::COMPARE_INVALID_SCOPE,
            self::COMPARE_UNSUPPORTED_SCOPE,
            self::COMPARE_MIXED_SCOPE,
            self::CAPTURE_MISSING_SOURCE_TENANT,
            self::CAPTURE_PROFILE_NOT_ACTIVE,
            self::CAPTURE_INVALID_SCOPE,
            self::CAPTURE_UNSUPPORTED_SCOPE,
            self::CAPTURE_INVENTORY_MISSING,
            self::CAPTURE_INVENTORY_BLOCKED,
            self::CAPTURE_INVENTORY_FAILED,
            self::CAPTURE_UNUSABLE_COVERAGE,
            self::CAPTURE_ZERO_SUBJECTS => 'unusable',
            default => null,
        };
    }

    public static function absencePattern(?string $reasonCode): ?string
    {
        return match (trim((string) $reasonCode)) {
            self::SNAPSHOT_BUILDING,
            self::SNAPSHOT_INCOMPLETE,
            self::SNAPSHOT_COMPLETION_PROOF_FAILED,
            self::SNAPSHOT_LEGACY_NO_PROOF,
            self::SNAPSHOT_LEGACY_CONTRADICTORY,
            self::COMPARE_NO_ACTIVE_SNAPSHOT,
            self::COMPARE_NO_CONSUMABLE_SNAPSHOT,
            self::COMPARE_SNAPSHOT_BUILDING,
            self::COMPARE_SNAPSHOT_INCOMPLETE => 'missing_input',
            self::CAPTURE_MISSING_SOURCE_TENANT,
            self::CAPTURE_PROFILE_NOT_ACTIVE,
            self::CAPTURE_ROLLOUT_DISABLED,
            self::CAPTURE_INVENTORY_MISSING,
            self::CAPTURE_INVENTORY_BLOCKED,
            self::CAPTURE_INVENTORY_FAILED,
            self::CAPTURE_UNUSABLE_COVERAGE,
            self::COMPARE_NO_ASSIGNMENT,
            self::COMPARE_PROFILE_NOT_ACTIVE,
            self::COMPARE_NO_ELIGIBLE_TARGET,
            self::COMPARE_INVALID_SNAPSHOT,
            self::COMPARE_INVALID_SCOPE,
            self::COMPARE_UNSUPPORTED_SCOPE,
            self::COMPARE_MIXED_SCOPE,
            self::COMPARE_ROLLOUT_DISABLED,
            self::SNAPSHOT_SUPERSEDED,
            self::COMPARE_SNAPSHOT_SUPERSEDED => 'blocked_prerequisite',
            self::SNAPSHOT_CAPTURE_FAILED => 'unavailable',
            self::CAPTURE_ZERO_SUBJECTS => 'missing_input',
            self::CAPTURE_INVALID_SCOPE,
            self::CAPTURE_UNSUPPORTED_SCOPE => 'unavailable',
            default => null,
        };
    }
}
