/**
 * Bridge functions to derive `RouteSpec` and `EventSpec` from `ActionSpec`.
 *
 * Action specs define the contract (method, input/output, auth, side effects).
 * Bridge functions produce transport-specific specs from them. HTTP-specific
 * concerns (path, handler) come from options.
 *
 * @module
 */
/** Derive the default HTTP method from side effects. */
export const derive_http_method = (side_effects) => {
    return side_effects ? 'POST' : 'GET';
};
/**
 * Derive a `RouteSpec` from an `ActionSpec` and options.
 *
 * Only `request_response` actions (which require non-null `auth`) can become routes.
 * `remote_notification` actions (auth null) should use `create_action_event_spec`.
 * `local_call` actions are not for HTTP transport.
 *
 * Error schemas are transport-specific (keyed by HTTP status codes) and belong
 * on the options, not the action spec. Action specs define the contract;
 * transport concerns like HTTP error codes are added at the bridge layer.
 *
 * @param spec - the action spec (must have non-null `auth`)
 * @param options - HTTP-specific options (path, handler, optional overrides)
 * @returns a `RouteSpec` ready for `apply_route_specs`
 * @throws Error if `spec.auth` is null (only `request_response` actions can
 *   become routes; notifications and local calls cannot)
 */
export const create_action_route_spec = (spec, options) => {
    if (spec.auth === null) {
        throw new Error(`Cannot derive route spec from action '${spec.method}': auth is null (only request_response actions with non-null auth can become routes)`);
    }
    return {
        method: options.http_method ?? derive_http_method(spec.side_effects),
        path: options.path,
        auth: options.auth ?? spec.auth,
        handler: options.handler,
        description: spec.description,
        ...(options.params ? { params: options.params } : {}),
        ...(options.query ? { query: options.query } : {}),
        input: spec.input,
        output: spec.output,
        ...(options.errors ? { errors: options.errors } : {}),
        transaction: spec.side_effects,
    };
};
/**
 * Derive an `EventSpec` from an `ActionSpec`.
 *
 * Only `remote_notification` actions can become push events.
 *
 * @param spec - the action spec (must have `kind: 'remote_notification'`)
 * @param options - optional event-specific options (channel)
 * @returns an `EventSpec` ready for `create_validated_broadcaster`
 * @throws Error if `spec.kind` is not `'remote_notification'`
 */
export const create_action_event_spec = (spec, options) => {
    if (spec.kind !== 'remote_notification') {
        throw new Error(`Cannot derive event spec from action '${spec.method}': kind is '${spec.kind}' (must be 'remote_notification')`);
    }
    return {
        method: spec.method,
        params: spec.input,
        description: spec.description,
        channel: options?.channel,
    };
};
