use std::future::Future;
use std::net::SocketAddr;
use futures::FutureExt;
use tokio::net::TcpListener;
use tokio::net::TcpStream;
use tokio::spawn;
use tokio_tungstenite::accept_async as accept_websocket;
use tokio_tungstenite::tungstenite::Error as WebSocketError;
use tokio_tungstenite::MaybeTlsStream;
use tokio_tungstenite::WebSocketStream as WsStream;
pub type WebSocketStream = WsStream<MaybeTlsStream<TcpStream>>;
pub async fn mock_server<F, R>(f: F) -> SocketAddr
where
F: FnOnce(WebSocketStream) -> R + Send + Sync + 'static,
R: Future<Output = Result<(), WebSocketError>> + Send + Sync + 'static,
{
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
let future = async move {
listener
.accept()
.map(Result::unwrap)
.then(|(stream, _addr)| accept_websocket(MaybeTlsStream::Plain(stream)))
.map(Result::unwrap)
.then(f)
.await
};
let _ = spawn(future);
addr
}