//! Protocol types for quicproquo.
//!
//! This crate contains both:
//! - **v1 (legacy)**: Cap'n Proto generated types from `schemas/*.capnp`
//! - **v2**: Protobuf generated types from `proto/qpq/v1/*.proto`
//!
//! # Design constraints
//!
//! - **No crypto** — key material never enters this crate.
//! - **No I/O** — callers own transport; this crate only converts bytes <-> types.
//! - **No async** — pure synchronous data-layer code.

// ════════════════════════════════════════════════════════════════════════════
// v1 (legacy): Cap'n Proto generated types
// ════════════════════════════════════════════════════════════════════════════

#![allow(unused_parens)]

pub mod auth_capnp {
    include!(concat!(env!("OUT_DIR"), "/auth_capnp.rs"));
}

pub mod delivery_capnp {
    include!(concat!(env!("OUT_DIR"), "/delivery_capnp.rs"));
}

pub mod node_capnp {
    include!(concat!(env!("OUT_DIR"), "/node_capnp.rs"));
}

pub mod federation_capnp {
    include!(concat!(env!("OUT_DIR"), "/federation_capnp.rs"));
}

/// Serialise a Cap'n Proto message builder to unpacked wire bytes.
pub fn to_bytes<A: capnp::message::Allocator>(
    msg: &capnp::message::Builder<A>,
) -> Result<Vec<u8>, capnp::Error> {
    let mut buf = Vec::new();
    capnp::serialize::write_message(&mut buf, msg)?;
    Ok(buf)
}

/// Deserialise unpacked wire bytes into a Cap'n Proto message.
pub fn from_bytes(
    bytes: &[u8],
) -> Result<capnp::message::Reader<capnp::serialize::OwnedSegments>, capnp::Error> {
    let mut options = capnp::message::ReaderOptions::new();
    options.traversal_limit_in_words(Some(1_048_576));
    let mut cursor = std::io::Cursor::new(bytes);
    capnp::serialize::read_message(&mut cursor, options)
}

/// Deserialise with custom [`ReaderOptions`].
pub fn from_bytes_with_options(
    bytes: &[u8],
    options: capnp::message::ReaderOptions,
) -> Result<capnp::message::Reader<capnp::serialize::OwnedSegments>, capnp::Error> {
    let mut cursor = std::io::Cursor::new(bytes);
    capnp::serialize::read_message(&mut cursor, options)
}

// ════════════════════════════════════════════════════════════════════════════
// v2: Protobuf (prost) generated types
// ════════════════════════════════════════════════════════════════════════════

/// Protobuf types for the v2 RPC protocol.
pub mod qpq {
    pub mod v1 {
        include!(concat!(env!("OUT_DIR"), "/qpq.v1.rs"));
    }
}

/// Method ID constants for the v2 RPC dispatch table.
pub mod method_ids {
    // Auth (100-103)
    pub const OPAQUE_REGISTER_START: u16 = 100;
    pub const OPAQUE_REGISTER_FINISH: u16 = 101;
    pub const OPAQUE_LOGIN_START: u16 = 102;
    pub const OPAQUE_LOGIN_FINISH: u16 = 103;

    // Delivery (200-205)
    pub const ENQUEUE: u16 = 200;
    pub const FETCH: u16 = 201;
    pub const FETCH_WAIT: u16 = 202;
    pub const PEEK: u16 = 203;
    pub const ACK: u16 = 204;
    pub const BATCH_ENQUEUE: u16 = 205;

    // Keys (300-304)
    pub const UPLOAD_KEY_PACKAGE: u16 = 300;
    pub const FETCH_KEY_PACKAGE: u16 = 301;
    pub const UPLOAD_HYBRID_KEY: u16 = 302;
    pub const FETCH_HYBRID_KEY: u16 = 303;
    pub const FETCH_HYBRID_KEYS: u16 = 304;

    // Channel (400)
    pub const CREATE_CHANNEL: u16 = 400;

    // Group management (410-413)
    pub const REMOVE_MEMBER: u16 = 410;
    pub const UPDATE_GROUP_METADATA: u16 = 411;
    pub const LIST_GROUP_MEMBERS: u16 = 412;
    pub const ROTATE_KEYS: u16 = 413;

    // User (500-501)
    pub const RESOLVE_USER: u16 = 500;
    pub const RESOLVE_IDENTITY: u16 = 501;

    // Key Transparency (510-520)
    pub const REVOKE_KEY: u16 = 510;
    pub const CHECK_REVOCATION: u16 = 511;
    pub const AUDIT_KEY_TRANSPARENCY: u16 = 520;

    // Blob (600-601)
    pub const UPLOAD_BLOB: u16 = 600;
    pub const DOWNLOAD_BLOB: u16 = 601;

    // Device (700-702, 710)
    pub const REGISTER_DEVICE: u16 = 700;
    pub const LIST_DEVICES: u16 = 701;
    pub const REVOKE_DEVICE: u16 = 702;
    pub const REGISTER_PUSH_TOKEN: u16 = 710;

    // P2P (800-802)
    pub const PUBLISH_ENDPOINT: u16 = 800;
    pub const RESOLVE_ENDPOINT: u16 = 801;
    pub const HEALTH: u16 = 802;

    // Federation (900-905)
    pub const RELAY_ENQUEUE: u16 = 900;
    pub const RELAY_BATCH_ENQUEUE: u16 = 901;
    pub const PROXY_FETCH_KEY_PACKAGE: u16 = 902;
    pub const PROXY_FETCH_HYBRID_KEY: u16 = 903;
    pub const PROXY_RESOLVE_USER: u16 = 904;
    pub const FEDERATION_HEALTH: u16 = 905;

    // Moderation (420-424)
    pub const REPORT_MESSAGE: u16 = 420;
    pub const BAN_USER: u16 = 421;
    pub const UNBAN_USER: u16 = 422;
    pub const LIST_REPORTS: u16 = 423;
    pub const LIST_BANNED: u16 = 424;

    // Recovery (750-752)
    pub const STORE_RECOVERY_BUNDLE: u16 = 750;
    pub const FETCH_RECOVERY_BUNDLE: u16 = 751;
    pub const DELETE_RECOVERY_BUNDLE: u16 = 752;

    // Account (950)
    pub const DELETE_ACCOUNT: u16 = 950;

    // Push event types (1000+)
    pub const PUSH_NEW_MESSAGE: u16 = 1000;
    pub const PUSH_TYPING: u16 = 1001;
    pub const PUSH_PRESENCE: u16 = 1002;
    pub const PUSH_MEMBERSHIP: u16 = 1003;
}

pub use prost;
pub use bytes;
