import { ZodType } from 'zod';

/**
 * Core Binder Types and Utilities
 *
 * This module provides the core types and utilities for the bindings system.
 * Bindings define standardized interfaces that integrations (MCPs) can implement.
 */

/**
 * ToolBinder defines a single tool within a binding.
 * It specifies the tool name, input/output schemas, and whether it's optional.
 *
 * @template TName - The tool name (can be a string or RegExp for pattern matching)
 * @template TInput - The input type (inferred from inputSchema)
 * @template TReturn - The return type (inferred from outputSchema)
 */
interface ToolBinder<TName extends string | RegExp = string, TInput = any, TReturn extends object | null | boolean = object, TStreamable extends boolean = boolean> {
    /** The name of the tool (e.g., "DECO_CHAT_CHANNELS_JOIN") */
    name: TName;
    /** Zod schema for validating tool input */
    inputSchema: ZodType<TInput>;
    /** Optional Zod schema for validating tool output */
    outputSchema?: TStreamable extends true ? never : ZodType<TReturn>;
    /**
     * Whether this tool is streamable.
     */
    streamable?: TStreamable;
    /**
     * Whether this tool is optional in the binding.
     * If true, an implementation doesn't need to provide this tool.
     */
    opt?: true;
}
/**
 * Binder represents a collection of tool definitions that form a binding.
 * A binding is like a TypeScript interface - it defines what tools must be implemented.
 *
 * @template TDefinition - Array of ToolBinder definitions
 *
 * @example
 * ```ts
 * const MY_BINDING = [{
 *   name: "MY_TOOL" as const,
 *   inputSchema: z.object({ id: z.string() }),
 *   outputSchema: z.object({ success: z.boolean() }),
 * }] as const satisfies Binder;
 * ```
 */
type Binder<TDefinition extends readonly ToolBinder[] = readonly ToolBinder[]> = TDefinition;
/**
 * Tool with schemas for validation
 */
interface ToolWithSchemas {
    name: string;
    inputSchema?: ZodType<any> | Record<string, unknown>;
    outputSchema?: ZodType<any> | Record<string, unknown>;
}
/**
 * Binding checker interface
 */
interface BindingChecker {
    /**
     * Check if a set of tools implements the binding with full schema validation.
     *
     * Validates:
     * - Tool name matches (exact or regex)
     * - Input schema: Tool accepts what binder requires (no removals from binder to tool)
     * - Output schema: Tool provides what binder expects (no removals from tool to binder)
     *
     * @param tools - Array of tools with names and schemas
     * @returns Promise<boolean> - true if all tools implement the binding correctly
     */
    isImplementedBy: (tools: ToolWithSchemas[]) => Promise<boolean>;
}
/**
 * Creates a binding checker with full schema validation using json-schema-diff.
 *
 * This performs strict compatibility checking:
 * - For input schemas: Validates that the tool can accept what the binder requires
 * - For output schemas: Validates that the tool provides what the binder expects
 *
 * @param binderTools - The binding definition to check against
 * @returns A binding checker with an async isImplementedBy method
 *
 * @example
 * ```ts
 * const checker = createBindingChecker(MY_BINDING);
 * const isCompatible = await checker.isImplementedBy(availableTools);
 * ```
 */
declare function createBindingChecker<TDefinition extends readonly ToolBinder[]>(binderTools: TDefinition): BindingChecker;

export { type Binder, type BindingChecker, type ToolBinder, type ToolWithSchemas, createBindingChecker };
