//! Shared output and yield types for HTTP request-response coroutines.
//!
//! Both [`Http10Send`] and [`Http11Send`] return [`HttpSendOutput`] on
//! success and emit [`HttpSendYield`] on every intermediate step.
//!
//! [`Http10Send`]: crate::rfc1945::send::Http10Send
//! [`Http11Send`]: crate::rfc9112::send::Http11Send

use alloc::vec::Vec;

use url::Url;

use crate::{coroutine::HttpYield, rfc9110::response::HttpResponse};

/// Terminal output of a successful HTTP request-response exchange.
#[derive(Clone, Debug)]
pub struct HttpSendOutput {
    /// The parsed response, body included.
    pub response: HttpResponse,
    /// Bytes already buffered past the end of the response.
    pub remaining: Vec<u8>,
    /// Whether the server signalled the connection can be reused.
    pub keep_alive: bool,
}

/// Per-step yield emitted by `Http10Send` / `Http11Send`; adds
/// [`Self::WantsRedirect`] to the standard [`HttpYield`] for 3xx responses.
#[derive(Debug)]
pub enum HttpSendYield {
    /// The coroutine wants bytes read from the stream and handed back
    /// on the next resume.
    WantsRead,
    /// The coroutine wants these bytes written to the stream.
    WantsWrite(Vec<u8>),
    /// The server answered with a 3xx and a parseable location; the
    /// caller decides whether to follow.
    WantsRedirect {
        /// The redirect target, resolved against the request URL.
        url: Url,
        /// The 3xx response itself.
        response: HttpResponse,
        /// Whether the server signalled the connection can be reused.
        keep_alive: bool,
        /// `false` when the redirect crosses scheme/host/port; do not
        /// forward credentials without user consent (RFC 9110 §15.4).
        same_origin: bool,
    },
}

impl From<HttpYield> for HttpSendYield {
    fn from(y: HttpYield) -> Self {
        match y {
            HttpYield::WantsRead => Self::WantsRead,
            HttpYield::WantsWrite(bytes) => Self::WantsWrite(bytes),
        }
    }
}
