<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Action;

/**
 * One read-back that has to hold before the invoker commits. It exists because several backend
 * controllers write nothing and say nothing when their preconditions are not met — a silent
 * no-op is indistinguishable from a success at the HTTP layer, so the only honest proof is to go
 * and look at the rows afterwards.
 */
final class VerifyAssertion
{
    /**
     * @param array<string,mixed> $expect column (or `n`/`minimum`) => literal or placeholder
     */
    private function __construct(
        public readonly VerifyKind $kind,
        public readonly string $query,
        public readonly array $expect,
    ) {
    }

    /**
     * @param array<mixed> $raw
     */
    public static function fromArray(array $raw): self
    {
        $expect = [];
        foreach (\is_array($raw['expect'] ?? null) ? $raw['expect'] : [] as $key => $value) {
            $expect[(string)$key] = $value;
        }

        return new self(
            VerifyKind::from(\is_string($raw['kind'] ?? null) ? $raw['kind'] : ''),
            \is_string($raw['query'] ?? null) ? $raw['query'] : '',
            $expect,
        );
    }
}
