use crate::*;

use poem::{
    http::uri::Scheme,
    web::{LocalAddr, RemoteAddr},
};

/// Re-export of `poem::Server`
pub use poem::Server as HttpServer;

impl poem::listener::Acceptor for HiddenService {
    type Io = DataStream;

    fn local_addr(&self) -> Vec<poem::web::LocalAddr> {
        let mut dest = vec![];
        if let Some(addr) = self.service.onion_address() {
            dest.push(poem::web::LocalAddr(poem::Addr::Custom(
                "onion",
                addr.display_unredacted().to_string().into(),
            )));
        }
        dest
    }

    async fn accept(&mut self) -> std::io::Result<(Self::Io, LocalAddr, RemoteAddr, Scheme)> {
        loop {
            if let Some((_addr, conn)) = self.handle().await? {
                return Ok((
                    conn,
                    self.local_addr().first().cloned().unwrap_or_default(),
                    poem::web::RemoteAddr::default(), // TODO: hook up _addr
                    poem::http::uri::Scheme::HTTP,
                ));
            }
        }
    }
}

impl poem::listener::Listener for HiddenService {
    type Acceptor = Self;

    async fn into_acceptor(self) -> std::io::Result<Self::Acceptor> {
        Ok(self)
    }
}
