use std::io::{Read, Write, Result};
use crate::session::Session;

/// This type implements `io::Read` and `io::Write`, encapsulating
/// a Session `S` and an underlying transport `T`, such as a socket.
///
/// This allows you to use a rustls Session like a normal stream.
pub struct Stream<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> {
    /// Our session
    pub sess: &'a mut S,

    /// The underlying transport, like a socket
    pub sock: &'a mut T,
}

impl<'a, S, T> Stream<'a, S, T> where S: 'a + Session, T: 'a + Read + Write {
    /// Make a new Stream using the Session `sess` and socket-like object
    /// `sock`.  This does not fail and does no IO.
    pub fn new(sess: &'a mut S, sock: &'a mut T) -> Stream<'a, S, T> {
        Stream { sess, sock }
    }

    /// If we're handshaking, complete all the IO for that.
    /// If we have data to write, write it all.
    fn complete_prior_io(&mut self) -> Result<()> {
        if self.sess.is_handshaking() {
            self.sess.complete_io(self.sock)?;
        }

        if self.sess.wants_write() {
            self.sess.complete_io(self.sock)?;
        }

        Ok(())
    }
}

impl<'a, S, T> Read for Stream<'a, S, T> where S: 'a + Session, T: 'a + Read + Write {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        self.complete_prior_io()?;

        // We call complete_io() in a loop since a single call may read only
        // a partial packet from the underlying transport. A full packet is
        // needed to get more plaintext, which we must do if EOF has not been
        // hit. Otherwise, we will prematurely signal EOF by returning 0. We
        // determine if EOF has actually been hit by checking if 0 bytes were
        // read from the underlying transport.
        while
            self.sess.wants_read() &&
            self.sess.complete_io(self.sock)?.0 != 0
        { }

        self.sess.read(buf)
    }
}

impl<'a, S, T> Write for Stream<'a, S, T> where S: 'a + Session, T: 'a + Read + Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.complete_prior_io()?;

        let len = self.sess.write(buf)?;

        // Try to write the underlying transport here, but don't let
        // any errors mask the fact we've consumed `len` bytes.
        // Callers will learn of permanent errors on the next call.
        let _ = self.sess.complete_io(self.sock);

        Ok(len)
    }

    fn flush(&mut self) -> Result<()> {
        self.complete_prior_io()?;

        self.sess.flush()?;
        if self.sess.wants_write() {
            self.sess.complete_io(self.sock)?;
        }
        Ok(())
    }
}

/// This type implements `io::Read` and `io::Write`, encapsulating
/// and owning a Session `S` and an underlying blocking transport
/// `T`, such as a socket.
///
/// This allows you to use a rustls Session like a normal stream.
pub struct StreamOwned<S: Session + Sized, T: Read + Write + Sized> {
    /// Our session
    pub sess: S,

    /// The underlying transport, like a socket
    pub sock: T,
}

impl<S, T> StreamOwned<S, T> where S: Session, T: Read + Write {
    /// Make a new StreamOwned taking the Session `sess` and socket-like
    /// object `sock`.  This does not fail and does no IO.
    ///
    /// This is the same as `Stream::new` except `sess` and `sock` are
    /// moved into the StreamOwned.
    pub fn new(sess: S, sock: T) -> StreamOwned<S, T> {
        StreamOwned { sess, sock }
    }

    /// Get a reference to the underlying socket
    pub fn get_ref(&self) -> &T {
        &self.sock
    }

    /// Get a mutable reference to the underlying socket
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.sock
    }
}

impl<'a, S, T> StreamOwned<S, T> where S: Session, T: Read + Write {
    fn as_stream(&'a mut self) -> Stream<'a, S, T> {
        Stream { sess: &mut self.sess, sock: &mut self.sock }
    }
}

impl<S, T> Read for StreamOwned<S, T> where S: Session, T: Read + Write {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        self.as_stream().read(buf)
    }
}

impl<S, T> Write for StreamOwned<S, T> where S: Session, T: Read + Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.as_stream().write(buf)
    }

    fn flush(&mut self) -> Result<()> {
        self.as_stream().flush()
    }
}

#[cfg(test)]
mod tests {
    use super::{Stream, StreamOwned};
    use crate::session::Session;
    use crate::client::ClientSession;
    use crate::server::ServerSession;
    use std::net::TcpStream;

    #[test]
    fn stream_can_be_created_for_session_and_tcpstream() {
        fn _foo<'a>(sess: &'a mut dyn Session, sock: &'a mut TcpStream) -> Stream<'a, dyn Session, TcpStream> {
            Stream {
                sess,
                sock,
            }
        }
    }

    #[test]
    fn streamowned_can_be_created_for_client_and_tcpstream() {
        fn _foo(sess: ClientSession, sock: TcpStream) -> StreamOwned<ClientSession, TcpStream> {
            StreamOwned {
                sess,
                sock,
            }
        }
    }

    #[test]
    fn streamowned_can_be_created_for_server_and_tcpstream() {
        fn _foo(sess: ServerSession, sock: TcpStream) -> StreamOwned<ServerSession, TcpStream> {
            StreamOwned {
                sess,
                sock,
            }
        }
    }
}
