use futures_util::future::TryFutureExt;
use lazy_static::lazy_static;
use rustls::{ClientConfig, OwnedTrustAnchor};
use rustls_pemfile::{certs, rsa_private_keys};
use std::convert::TryFrom;
use std::io::{BufReader, Cursor, ErrorKind};
use std::net::SocketAddr;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::time::Duration;
use std::{io, thread};
use tokio::io::{copy, split, AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::{runtime, time};
use tokio_rustls::{LazyConfigAcceptor, TlsAcceptor, TlsConnector};

const CERT: &str = include_str!("end.cert");
const CHAIN: &[u8] = include_bytes!("end.chain");
const RSA: &str = include_str!("end.rsa");

lazy_static! {
    static ref TEST_SERVER: (SocketAddr, &'static str, &'static [u8]) = {
        let cert = certs(&mut BufReader::new(Cursor::new(CERT)))
            .unwrap()
            .drain(..)
            .map(rustls::Certificate)
            .collect();
        let mut keys = rsa_private_keys(&mut BufReader::new(Cursor::new(RSA))).unwrap();
        let mut keys = keys.drain(..).map(rustls::PrivateKey);

        let config = rustls::ServerConfig::builder()
            .with_safe_defaults()
            .with_no_client_auth()
            .with_single_cert(cert, keys.next().unwrap())
            .unwrap();
        let acceptor = TlsAcceptor::from(Arc::new(config));

        let (send, recv) = channel();

        thread::spawn(move || {
            let runtime = runtime::Builder::new_current_thread()
                .enable_io()
                .build()
                .unwrap();
            let runtime = Arc::new(runtime);
            let runtime2 = runtime.clone();

            let done = async move {
                let addr = SocketAddr::from(([127, 0, 0, 1], 0));
                let listener = TcpListener::bind(&addr).await?;

                send.send(listener.local_addr()?).unwrap();

                loop {
                    let (stream, _) = listener.accept().await?;

                    let acceptor = acceptor.clone();
                    let fut = async move {
                        let stream = acceptor.accept(stream).await?;

                        let (mut reader, mut writer) = split(stream);
                        copy(&mut reader, &mut writer).await?;

                        Ok(()) as io::Result<()>
                    }
                    .unwrap_or_else(|err| eprintln!("server: {:?}", err));

                    runtime2.spawn(fut);
                }
            }
            .unwrap_or_else(|err: io::Error| eprintln!("server: {:?}", err));

            runtime.block_on(done);
        });

        let addr = recv.recv().unwrap();
        (addr, "testserver.com", CHAIN)
    };
}

fn start_server() -> &'static (SocketAddr, &'static str, &'static [u8]) {
    &*TEST_SERVER
}

async fn start_client(addr: SocketAddr, domain: &str, config: Arc<ClientConfig>) -> io::Result<()> {
    const FILE: &[u8] = include_bytes!("../README.md");

    let domain = rustls::ServerName::try_from(domain).unwrap();
    let config = TlsConnector::from(config);
    let mut buf = vec![0; FILE.len()];

    let stream = TcpStream::connect(&addr).await?;
    let mut stream = config.connect(domain, stream).await?;
    stream.write_all(FILE).await?;
    stream.flush().await?;
    stream.read_exact(&mut buf).await?;

    assert_eq!(buf, FILE);

    Ok(())
}

#[tokio::test]
async fn pass() -> io::Result<()> {
    let (addr, domain, chain) = start_server();

    // TODO: not sure how to resolve this right now but since
    // TcpStream::bind now returns a future it creates a race
    // condition until its ready sometimes.
    use std::time::*;
    tokio::time::sleep(Duration::from_secs(1)).await;

    let chain = certs(&mut std::io::Cursor::new(*chain)).unwrap();
    let trust_anchors = chain
        .iter()
        .map(|cert| {
            let ta = webpki::TrustAnchor::try_from_cert_der(&cert[..]).unwrap();
            OwnedTrustAnchor::from_subject_spki_name_constraints(
                ta.subject,
                ta.spki,
                ta.name_constraints,
            )
        })
        .collect::<Vec<_>>();
    let mut root_store = rustls::RootCertStore::empty();
    root_store.add_server_trust_anchors(trust_anchors.into_iter());
    let config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_store)
        .with_no_client_auth();
    let config = Arc::new(config);

    start_client(*addr, domain, config).await?;

    Ok(())
}

#[tokio::test]
async fn fail() -> io::Result<()> {
    let (addr, domain, chain) = start_server();

    let chain = certs(&mut std::io::Cursor::new(*chain)).unwrap();
    let trust_anchors = chain
        .iter()
        .map(|cert| {
            let ta = webpki::TrustAnchor::try_from_cert_der(&cert[..]).unwrap();
            OwnedTrustAnchor::from_subject_spki_name_constraints(
                ta.subject,
                ta.spki,
                ta.name_constraints,
            )
        })
        .collect::<Vec<_>>();
    let mut root_store = rustls::RootCertStore::empty();
    root_store.add_server_trust_anchors(trust_anchors.into_iter());
    let config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_store)
        .with_no_client_auth();
    let config = Arc::new(config);

    assert_ne!(domain, &"google.com");
    let ret = start_client(*addr, "google.com", config).await;
    assert!(ret.is_err());

    Ok(())
}

#[tokio::test]
async fn test_lazy_config_acceptor() -> io::Result<()> {
    let (sconfig, cconfig) = utils::make_configs();
    use std::convert::TryFrom;

    let (cstream, sstream) = tokio::io::duplex(1200);
    let domain = rustls::ServerName::try_from("localhost").unwrap();
    tokio::spawn(async move {
        let connector = crate::TlsConnector::from(cconfig);
        let mut client = connector.connect(domain, cstream).await.unwrap();
        client.write_all(b"hello, world!").await.unwrap();

        let mut buf = Vec::new();
        client.read_to_end(&mut buf).await.unwrap();
    });

    let acceptor = LazyConfigAcceptor::new(rustls::server::Acceptor::new().unwrap(), sstream);
    let start = acceptor.await.unwrap();
    let ch = start.client_hello();

    assert_eq!(ch.server_name(), Some("localhost"));
    assert_eq!(
        ch.alpn()
            .map(|protos| protos.collect::<Vec<_>>())
            .unwrap_or(Vec::new()),
        Vec::<&[u8]>::new()
    );

    let mut stream = start.into_stream(sconfig).await.unwrap();
    let mut buf = [0; 13];
    stream.read_exact(&mut buf).await.unwrap();
    assert_eq!(&buf[..], b"hello, world!");

    stream.write_all(b"bye").await.unwrap();
    Ok(())
}

// This test is a follow-up from https://github.com/tokio-rs/tls/issues/85
#[tokio::test]
async fn lazy_config_acceptor_eof() {
    let buf = Cursor::new(Vec::new());
    let acceptor = LazyConfigAcceptor::new(rustls::server::Acceptor::new().unwrap(), buf);

    let accept_result = match time::timeout(Duration::from_secs(3), acceptor).await {
        Ok(res) => res,
        Err(_elapsed) => panic!("timeout"),
    };

    match accept_result {
        Ok(_) => panic!("accepted a connection from zero bytes of data"),
        Err(e) if e.kind() == ErrorKind::UnexpectedEof => {}
        Err(e) => panic!("unexpected error: {:?}", e),
    }
}

// Include `utils` module
include!("utils.rs");
