<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Audit;

use JTL\DB\DbInterface;
use Plugin\tnt_mcp\src\Mcp\Support\ArgRedactor;
use stdClass;
use Throwable;

/**
 * Append-only audit of every MCP call (identity, tool, args, outcome, time) into tnt_mcp_audit.
 * Never blocks the call: a failed write is swallowed so auditing can't take the server down.
 * Constructed with a null DB in tests / before the route is wired, where it is simply a no-op.
 */
final class AuditLogger
{
    public function __construct(private readonly ?DbInterface $db = null)
    {
    }

    /** @param array<string,mixed> $args */
    public function record(string $tokenId, string $tool, array $args, string $outcome): void
    {
        if ($this->db === null) {
            return;
        }

        try {
            $row           = new stdClass();
            $row->cTokenId = mb_substr($tokenId, 0, 191);
            $row->cTool    = mb_substr($tool, 0, 191);
            // Never store raw argument values — see {@see ArgRedactor}.
            $row->cArgs    = (string)json_encode(ArgRedactor::redact($args));
            $row->cOutcome = mb_substr($outcome, 0, 64);
            $row->dCreated = date('Y-m-d H:i:s');
            $this->db->insertRow('tnt_mcp_audit', $row);
        } catch (Throwable) {
            // Auditing is best-effort; a logging failure must never break the tool call.
        }
    }
}
