use std::io::{Write};
use std::net::TcpStream;
use std::sync::Arc;
use std::time::Duration;
use openssl::ssl::{SslAcceptor, SslStream};
use crate::config::Config;
use crate::stream::LineReader;

pub enum Service {
    Http(TcpStream, LineReader),
    Https(SslStream<TcpStream>, LineReader),
}

impl Service {
    pub fn new(stream: TcpStream, config: Config, ssl: Arc<SslAcceptor>) -> Result<Service, String> {
        // 服务器读取超时设置
        stream.set_read_timeout(Some(Duration::from_secs(3))).unwrap();
        // 服务器写入超时设置
        stream.set_write_timeout(Some(Duration::from_secs(3))).unwrap();

        let line_reader = LineReader::new();
        let that = if config.ssl {
            match ssl.accept(stream.try_clone().unwrap()) {
                Ok(stream_ssl) => Self::Https(stream_ssl, line_reader),
                Err(_) => Self::Http(stream, line_reader)
            }
        } else {
            Self::Http(stream, line_reader)
        };
        Ok(that)
    }
    pub fn request_header(&mut self) -> Result<Vec<String>, String> {
        let text = match self {
            Service::Http(e, line) => {
                line.read(e)?
            }
            Service::Https(e, line) => {
                line.read_ssl(e)?
            }
        };
        Ok(text)
    }
    pub fn request_body(&mut self, content_length: usize) -> Result<Vec<u8>, String> {
        let text = match self {
            Service::Http(e, line) => {
                line.read_body(e, content_length)?
            }
            Service::Https(e, line) => {
                line.read_body_ssl(e, content_length)?
            }
        };
        Ok(text)
    }

    pub fn response(&mut self, res: String) -> Result<usize, String> {
        match self {
            Service::Http(e, _) => {
                match e.write(res.as_bytes()) {
                    Ok(e) => Ok(e),
                    Err(e) => Err(format!("发送失败: {}", e.to_string()))
                }
            }
            Service::Https(e, _) => {
                match e.ssl_write(res.as_bytes()) {
                    Ok(e) => Ok(e),
                    Err(e) => Err(format!("发送失败: {}", e.to_string()))
                }
            }
        }
    }
}
