//! The resource state machine (`ARCHITECTURE.md` §3.8).
//!
//! Resources are segmented payload transfers over a link — what `rncp`, file
//! transfers, and large LXMF messages rely on. This is the largest single piece
//! of functionality missing from the Beechat baseline. Per §3.8 it is **not**
//! the first thing to implement; the announce subsystem and a live interop test
//! come first.
//!
//! The part bitmaps (`received` / `pending`) and the progress callback from §3.8
//! pull in a bitmap dependency and are added with the Phase 3 logic; they are
//! deliberately omitted from this v0 skeleton.

use std::time::Instant;

use plexus_core::AddressHash;

/// Direction of a resource transfer.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResourceDirection {
    /// We are sending.
    Outbound,
    /// We are receiving.
    Inbound,
}

/// Why a resource transfer failed.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResourceFailReason {
    /// Timed out.
    Timeout,
    /// Cancelled by either side.
    Cancelled,
    /// Reassembled payload hash did not match the advertisement.
    HashMismatch,
    /// The underlying link closed.
    LinkClosed,
}

/// Resource transfer state.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResourceState {
    /// Advertised, not yet transferring.
    Advertised,
    /// Parts in flight.
    Transferring,
    /// Receiver-side, all parts in, reassembling.
    Assembling,
    /// Done.
    Complete,
    /// Failed.
    Failed {
        /// Failure cause.
        reason: ResourceFailReason,
    },
    /// Cancelled.
    Cancelled,
}

/// A segmented payload transfer over a link (§3.8).
pub struct Resource {
    /// SHA-256 of the whole payload.
    pub id: [u8; 32],
    /// Link the transfer runs over.
    pub link_id: AddressHash,
    /// Total payload size in bytes.
    pub total_size: u64,
    /// Size of each part.
    pub part_size: u32,
    /// Number of parts.
    pub part_count: u32,
    /// Transfer direction.
    pub direction: ResourceDirection,
    /// Current state.
    pub state: ResourceState,
    started_at: Instant,
}

/// Resource-transfer events surfaced to the host.
#[derive(Debug)]
pub enum ResourceEvent {
    /// A transfer started.
    Started {
        /// Resource id.
        id: [u8; 32],
        /// Total size in bytes.
        total_size: u64,
    },
    /// Progress update.
    Progress {
        /// Resource id.
        id: [u8; 32],
        /// Parts received so far.
        received: u32,
        /// Total parts.
        total: u32,
    },
    /// Transfer complete with the reassembled payload.
    Complete {
        /// Resource id.
        id: [u8; 32],
        /// The reassembled payload.
        data: Vec<u8>,
    },
    /// Transfer failed.
    Failed {
        /// Resource id.
        id: [u8; 32],
        /// Failure cause.
        reason: ResourceFailReason,
    },
}

/// Table of in-flight resources.
#[derive(Default)]
pub struct ResourceTable {}
