<?php

declare(strict_types=1);

final class MyronMcpOperatingContract
{
    private const INSTRUCTIONS = 'Operate MyronCMS through existing templates, registered composable sections, and design tokens first. Treat Design tools as shared presentation-system ownership and Content tools as authored page/data ownership. Compose or reuse governed sections before introducing new surface code. Use custom CSS, JavaScript, libraries, or fonts only as a minimal last resort when templates, section contracts, variants, and tokens cannot express the requirement; prefer the alternatives named in tool metadata. Honor each tool’s scopes, preconditions, postconditions, and declared side effects.';

    public static function instructions(): string
    {
        return self::INSTRUCTIONS;
    }

    public static function description(MyronActionMetadata $metadata): string
    {
        $parts = [$metadata->summary];
        if ($metadata->preconditions !== []) {
            $parts[] = 'Preconditions: ' . implode('; ', $metadata->preconditions) . '.';
        }
        if ($metadata->sideEffects !== []) {
            $parts[] = 'Side effects: ' . implode('; ', $metadata->sideEffects) . '.';
        }
        if ($metadata->postconditions !== []) {
            $parts[] = 'Postconditions: ' . implode('; ', $metadata->postconditions) . '.';
        }
        $parts[] = 'Audience class: ' . $metadata->audienceClass . '.';
        if ($metadata->mcpAltitude !== null) {
            $parts[] = 'Operating altitude: ' . $metadata->mcpAltitude . '.';
            if ($metadata->mcpPreferInstead !== []) {
                $parts[] = 'Prefer instead: ' . implode(', ', $metadata->mcpPreferInstead) . '.';
            }
        }
        return implode(' ', $parts);
    }

    /** @return array<string, mixed> */
    public static function meta(MyronActionMetadata $metadata): array
    {
        $operating = [
            'audienceClass' => $metadata->audienceClass,
            'sideEffects' => $metadata->sideEffects,
            'preconditions' => $metadata->preconditions,
            'postconditions' => $metadata->postconditions,
        ];
        if ($metadata->mcpAltitude !== null) {
            $operating['altitude'] = $metadata->mcpAltitude;
            $operating['preferInstead'] = $metadata->mcpPreferInstead;
        }
        return ['com.myroncms/operating' => $operating];
    }

    /** @return array<string, bool|string> */
    public static function annotations(MyronActionMetadata $metadata, string $toolName): array
    {
        $readOnly = in_array(strtoupper($metadata->method), ['GET', 'HEAD'], true);
        $effects = strtolower(implode(' ', $metadata->sideEffects));
        $destructive = preg_match('/\b(delete|deletes|remove|removes|revoke|revokes|reset|drops|purge|destroy)\b/', $effects) === 1;
        $annotations = [
            'title' => ucwords(str_replace('_', ' ', $toolName)),
            'readOnlyHint' => $readOnly,
            'destructiveHint' => $destructive,
        ];
        if ($readOnly) {
            $annotations['idempotentHint'] = true;
        }
        if (preg_match('/\b(remote|external|outbound|webhook|mail|network|download)\b/', $effects) === 1) {
            $annotations['openWorldHint'] = true;
        }
        return $annotations;
    }
}
