<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Action;

/**
 * The whole before-snapshot instruction for one action. `maxRows` is the interesting field: it is
 * a promise limiter, not a guard — exceeding it does not refuse the action, it writes the journal
 * entry as not-undoable and makes the tool say so, which is the only version of undo worth
 * offering.
 */
final class JournalSpec
{
    /**
     * @param list<JournalScope> $scope
     */
    private function __construct(
        public readonly array $scope,
        public readonly UndoStrategy $undo,
        public readonly int $maxRows,
    ) {
    }

    /**
     * @param array<mixed> $raw
     */
    public static function fromArray(array $raw): self
    {
        $scope = [];
        foreach (\is_array($raw['scope'] ?? null) ? $raw['scope'] : [] as $entry) {
            if (\is_array($entry)) {
                $scope[] = JournalScope::fromArray($entry);
            }
        }

        return new self(
            $scope,
            UndoStrategy::from(\is_string($raw['undo'] ?? null) ? $raw['undo'] : ''),
            (int)($raw['maxRows'] ?? 0),
        );
    }

    /** @return list<string> tables covered by the snapshot, in declaration order */
    public function tables(): array
    {
        return \array_map(static fn (JournalScope $scope): string => $scope->table, $this->scope);
    }
}
