/**
 * MCP JSON-RPC message types used by the proxy.
 */

export interface JsonRpcRequest {
  jsonrpc: '2.0';
  id: string | number;
  method: string;
  params?: Record<string, unknown>;
}

export interface JsonRpcResponse {
  jsonrpc: '2.0';
  id: string | number;
  result?: unknown;
  error?: JsonRpcError;
}

export interface JsonRpcNotification {
  jsonrpc: '2.0';
  method: string;
  params?: Record<string, unknown>;
}

export interface JsonRpcError {
  code: number;
  message: string;
  data?: unknown;
}

export type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;

/** Configuration for an upstream MCP server */
export interface UpstreamConfig {
  /** Server ID from mcpd */
  serverId: string;
  /** Human-readable name */
  name: string;
  /** Transport type */
  transport: 'stdio' | 'sse' | 'streamable-http';
  /** For STDIO: command + args */
  command?: string;
  args?: string[];
  /** For HTTP transports: URL */
  url?: string;
  /** Environment variables to pass */
  env?: Record<string, string>;
}

/** Proxy server configuration */
export interface ProxyConfig {
  /** Port for the proxy to listen on */
  port: number;
  /** Host to bind to */
  host: string;
  /** mcpd daemon URL for fetching server configs */
  daemonUrl: string;
  /** Upstream servers to proxy */
  upstreams: UpstreamConfig[];
}

/** A running upstream connection */
export interface UpstreamConnection {
  /** Server name */
  name: string;
  /** Human-readable description of the server's purpose */
  description?: string;
  /** Send a JSON-RPC request and get a response */
  send(request: JsonRpcRequest): Promise<JsonRpcResponse>;
  /** Disconnect from the upstream */
  close(): Promise<void>;
  /** Whether the connection is alive */
  isAlive(): boolean;
  /** Register a handler for notifications from this upstream */
  onNotification?(handler: (notification: JsonRpcNotification) => void): void;
}
