import { stringify as stringifyYaml } from "yaml";
/**
 * Serializes a proto `Agent` into the canonical Stigmer YAML format.
 *
 * This is the inverse of {@link parseResourceYaml} — the serialized YAML
 * is round-trip compatible and can be fed back through `parseResourceYaml`
 * to produce a valid `AgentInput`.
 *
 * Only emits `apiVersion`, `kind`, `metadata`, and `spec`. The `status`
 * field is system-managed and never included in the YAML output.
 *
 * Uses snake_case field names in the YAML to match the proto canonical form,
 * which is the format expected by both the backend and `parseResourceYaml`.
 *
 * @param agent - The proto `Agent` resource to serialize.
 * @returns A YAML string suitable for editing and re-applying.
 *
 * @example
 * ```ts
 * import { serializeAgentYaml } from "@stigmer/react";
 *
 * const yaml = serializeAgentYaml(agent);
 * const file = new File([yaml], "my-agent.yaml", { type: "text/yaml" });
 * ```
 *
 * @see {@link parseResourceYaml} for the inverse operation
 */
export function serializeAgentYaml(agent) {
    const doc = {
        apiVersion: agent.apiVersion || "agentic.stigmer.ai/v1",
        kind: agent.kind || "Agent",
        metadata: buildMetadata(agent.metadata),
        spec: buildAgentSpec(agent.spec),
    };
    return stringifyYaml(doc, { lineWidth: 0, blockQuote: "literal" });
}
/**
 * Serializes a proto `McpServer` into the canonical Stigmer YAML format.
 *
 * This is the inverse of {@link parseResourceYaml} for McpServer resources.
 * Same round-trip guarantee and snake_case convention as {@link serializeAgentYaml}.
 *
 * @param mcpServer - The proto `McpServer` resource to serialize.
 * @returns A YAML string suitable for editing and re-applying.
 *
 * @example
 * ```ts
 * import { serializeMcpServerYaml } from "@stigmer/react";
 *
 * const yaml = serializeMcpServerYaml(mcpServer);
 * const file = new File([yaml], "my-server.yaml", { type: "text/yaml" });
 * ```
 *
 * @see {@link parseResourceYaml} for the inverse operation
 */
export function serializeMcpServerYaml(mcpServer) {
    const doc = {
        apiVersion: mcpServer.apiVersion || "agentic.stigmer.ai/v1",
        kind: mcpServer.kind || "McpServer",
        metadata: buildMetadata(mcpServer.metadata),
        spec: buildMcpServerSpec(mcpServer.spec),
    };
    return stringifyYaml(doc, { lineWidth: 0, blockQuote: "literal" });
}
// ---------------------------------------------------------------------------
// Metadata
// ---------------------------------------------------------------------------
function buildMetadata(metadata) {
    if (!metadata)
        return {};
    const result = {
        name: metadata.name,
    };
    if (metadata.org) {
        result.org = metadata.org;
    }
    if (metadata.slug && metadata.slug !== metadata.name) {
        result.slug = metadata.slug;
    }
    if (hasEntries(metadata.labels)) {
        result.labels = { ...metadata.labels };
    }
    return result;
}
// ---------------------------------------------------------------------------
// Agent spec
// ---------------------------------------------------------------------------
function buildAgentSpec(spec) {
    if (!spec)
        return {};
    const result = {};
    if (spec.description) {
        result.description = spec.description;
    }
    if (spec.iconUrl) {
        result.icon_url = spec.iconUrl;
    }
    if (spec.instructions) {
        result.instructions = spec.instructions;
    }
    if (spec.mcpServerUsages.length > 0) {
        result.mcp_server_usages = spec.mcpServerUsages.map(serializeMcpServerUsage);
    }
    if (spec.skillRefs.length > 0) {
        result.skill_refs = spec.skillRefs.map(serializeResourceRef);
    }
    if (spec.subAgents.length > 0) {
        result.sub_agents = spec.subAgents.map(serializeSubAgent);
    }
    if (hasEntries(spec.env)) {
        const env = serializeEnv(spec.env);
        if (env) {
            result.env = env;
        }
    }
    return result;
}
function serializeMcpServerUsage(usage) {
    const result = {};
    if (usage.mcpServerRef) {
        result.mcp_server_ref = serializeResourceRef(usage.mcpServerRef);
    }
    if (usage.enabledTools.length > 0) {
        result.enabled_tools = [...usage.enabledTools];
    }
    if (usage.toolApprovalOverrides.length > 0) {
        result.tool_approval_overrides =
            usage.toolApprovalOverrides.map(serializeToolApprovalOverride);
    }
    return result;
}
function serializeToolApprovalOverride(override) {
    const result = {
        tool_name: override.toolName,
        requires_approval: override.requiresApproval,
    };
    if (override.message) {
        result.message = override.message;
    }
    return result;
}
function serializeSubAgent(sub) {
    const result = {
        name: sub.name,
    };
    if (sub.description) {
        result.description = sub.description;
    }
    if (sub.instructions) {
        result.instructions = sub.instructions;
    }
    if (sub.modelOverride) {
        result.model_override = sub.modelOverride;
    }
    if (sub.mcpAccess.length > 0) {
        result.mcp_access = sub.mcpAccess.map(serializeMcpAccess);
    }
    if (sub.skillRefs.length > 0) {
        result.skill_refs = sub.skillRefs.map(serializeResourceRef);
    }
    return result;
}
function serializeMcpAccess(access) {
    const result = {
        mcp_server: access.mcpServer,
    };
    if (access.enabledTools.length > 0) {
        result.enabled_tools = [...access.enabledTools];
    }
    return result;
}
// ---------------------------------------------------------------------------
// McpServer spec
// ---------------------------------------------------------------------------
function buildMcpServerSpec(spec) {
    if (!spec)
        return {};
    const result = {};
    if (spec.description) {
        result.description = spec.description;
    }
    if (spec.iconUrl) {
        result.icon_url = spec.iconUrl;
    }
    if (spec.tags.length > 0) {
        result.tags = [...spec.tags];
    }
    if (spec.serverType.case === "stdio") {
        result.stdio = serializeStdioConfig(spec.serverType.value);
    }
    else if (spec.serverType.case === "http") {
        result.http = serializeHttpConfig(spec.serverType.value);
    }
    if (spec.defaultEnabledTools.length > 0) {
        result.default_enabled_tools = [...spec.defaultEnabledTools];
    }
    if (spec.pinnedToolApprovals.length > 0) {
        result.pinned_tool_approvals =
            spec.pinnedToolApprovals.map(serializeToolApprovalPolicy);
    }
    if (hasEntries(spec.env)) {
        const env = serializeEnv(spec.env);
        if (env) {
            result.env = env;
        }
    }
    return result;
}
function serializeStdioConfig(config) {
    const result = {
        command: config.command,
    };
    if (config.args.length > 0) {
        result.args = [...config.args];
    }
    if (config.workingDir) {
        result.working_dir = config.workingDir;
    }
    return result;
}
function serializeHttpConfig(config) {
    const result = {
        url: config.url,
    };
    if (hasEntries(config.headers)) {
        result.headers = { ...config.headers };
    }
    if (hasEntries(config.queryParams)) {
        result.query_params = { ...config.queryParams };
    }
    if (config.timeoutSeconds > 0) {
        result.timeout_seconds = config.timeoutSeconds;
    }
    return result;
}
function serializeToolApprovalPolicy(policy) {
    const result = {
        tool_name: policy.toolName,
    };
    if (policy.message) {
        result.message = policy.message;
    }
    return result;
}
// ---------------------------------------------------------------------------
// Shared serializers
// ---------------------------------------------------------------------------
function serializeResourceRef(ref) {
    const result = {};
    if (ref.org) {
        result.org = ref.org;
    }
    if (ref.kind) {
        result.kind = ref.kind;
    }
    result.slug = ref.slug;
    if (ref.version) {
        result.version = ref.version;
    }
    return result;
}
function serializeEnv(env) {
    const keys = Object.keys(env);
    if (keys.length === 0)
        return undefined;
    const result = {};
    for (const [key, val] of Object.entries(env)) {
        const entry = {};
        if (val.isSecret) {
            entry.is_secret = val.isSecret;
        }
        if (val.description) {
            entry.description = val.description;
        }
        if (val.optional) {
            entry.optional = val.optional;
        }
        result[key] = entry;
    }
    return result;
}
// ---------------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------------
function hasEntries(obj) {
    if (!obj)
        return false;
    return Object.keys(obj).length > 0;
}
//# sourceMappingURL=serialize-resource-yaml.js.map