// Brahman — Protocolo central (handshake & ciclo de vida)
//
// Esta interfaz es el contrato de los módulos "conscientes". Los módulos
// agnósticos sólo presentan un manifest TOML y son supervisados por convención
// mínima; los módulos con WIT pueden negociar capacidades, reportar estado y
// recibir señales del Admin.
//
// Versionado: este archivo declara `0.1.0`. Cambios major requieren un nuevo
// archivo (`protocol-v2.wit`); cambios minor son aditivos.

package brahman:protocol@0.1.0;

interface types {
    /// Identificador opaco emitido por el Admin tras un handshake exitoso.
    type session-id = string;

    /// Timestamp UNIX en segundos.
    type unix-ts = u64;

    record module-info {
        /// Nombre canónico (debe coincidir con el manifest).
        name: string,
        /// SemVer del módulo.
        version: string,
        /// Versión del protocolo Brahman implementada.
        protocol-version: string,
        /// Capacidades que ofrece (ids libres, idealmente URIs).
        provides: list<string>,
        /// Capacidades que requiere para arrancar.
        requires: list<string>,
    }

    record admin-info {
        /// Versión del Admin que aceptó el handshake.
        version: string,
        /// Versión del protocolo soportada por el Admin.
        protocol-version: string,
        /// Identificador de sesión asignado.
        session: session-id,
        /// Si el Init está vinculado al Admin actualmente.
        init-attached: bool,
    }

    /// Errores comunes durante negociación o ciclo de vida.
    variant protocol-error {
        protocol-mismatch(string),
        unauthorized(string),
        capability-unmet(string),
        rejected(string),
        internal(string),
    }
}

interface handshake {
    use types.{module-info, admin-info, protocol-error, session-id};

    /// Negociación inicial de un módulo con el Admin.
    /// El Admin valida protocolo, capacidades requeridas y permisos.
    hello: func(info: module-info) -> result<admin-info, protocol-error>;

    /// Cierre limpio (drena conexiones, libera recursos).
    farewell: func(session: session-id) -> result<_, protocol-error>;

    /// Latido para mantener viva la sesión. Devuelve el reloj del Admin.
    ping: func(session: session-id) -> result<u64, protocol-error>;
}

interface lifecycle {
    use types.{session-id, unix-ts, protocol-error};

    enum module-state {
        initializing,
        ready,
        running,
        suspended,
        degraded,
        terminating,
    }

    record state-report {
        state: module-state,
        timestamp: unix-ts,
        detail: option<string>,
    }

    /// Reporta cambio de estado al Admin (telemetría → Init si está adjunto).
    report-state: func(session: session-id, report: state-report) -> result<_, protocol-error>;

    /// Señal del Admin solicitando suspensión cooperativa.
    on-suspend: func(session: session-id) -> result<_, protocol-error>;

    /// Señal del Admin solicitando reanudación.
    on-resume: func(session: session-id) -> result<_, protocol-error>;
}

/// Mundo que un módulo Brahman implementa.
world module {
    import handshake;
    import lifecycle;

    /// Punto de entrada que el Admin invoca tras instanciar el componente.
    export run: func() -> result<_, string>;
}

/// Mundo que el Admin implementa (host-side) para los módulos.
world admin-host {
    export handshake;
    export lifecycle;
}
