mod base64;
pub mod stream;
pub mod config;
mod encoding;
pub mod request;
pub mod response;
pub mod websocket;
use crate::stream::{Protocol, Scheme};
use crate::config::{Config};
use crate::request::{Method, Request, Upgrade};
use crate::response::Response;
use crate::websocket::{CloseCode, ErrorCode, Message, Websocket, USERS};
use log::{error, info, warn};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use std::io::{Error};
use std::net::{IpAddr, SocketAddr, TcpListener};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::{io, thread};
use std::fmt::Debug;

/// 网络服务
#[derive(Clone, Debug)]
pub struct WebServer;

impl WebServer {
    /// 后台服务器
    pub fn new_service(config: &Config, factory: fn(out: Websocket) -> Box<dyn Handler>) {
        loop {
            match WebServer::service(&config.clone(), factory) {
                Ok(()) => {}
                Err(e) => error!("服务器错误: {}[{}]: {}", file!(), line!(), e),
            }
            warn!("服务器 1秒后重启");
            thread::sleep(Duration::from_secs(1));
        }
    }
    fn service(config: &Config, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
        info!("==================== 网络服务 服务信息 ====================");
        info!("日志记录: {}",if config.log {"开启"} else {"关闭"});
        info!("调试模式: {}",if config.debug { "开启" } else { "关闭" });
        info!("地    址: {}", config.host);
        info!("端 口 号: {}", config.port);
        info!("服务地址: {}://{}{}",if config.https { "https" } else { "http" },config.host,if config.port > 0 {format!(":{}", config.port)} else {String::new()});
        info!("根 目 录: {}", config.root_path.to_str().unwrap());
        info!("访问目录: {}", config.public);
        info!("运行目录: {}", config.runtime);
        info!("SSL/TLS: {}",if config.https { "开启" } else { "关闭" });

        if config.https {
            info!("证书目录KEY: {:?}", config.tls.key);
            info!("证书目录PEM: {:?}", config.tls.certs);
        }

        let addrs = [SocketAddr::from((
            IpAddr::V4(config.host.parse().unwrap()),
            config.port,
        ))];
        let listener = TcpListener::bind(&addrs[..])?;
        info!("==================== 网络服务 启动成功 ====================");

        let acceptor = Self::ssl(&config.clone())?;
        for stream in listener.incoming() {
            match stream {
                Ok(stream) => {
                    let config_new = config.clone();
                    let acceptor_new = acceptor.clone();

                    thread::spawn(move || -> io::Result<()> {
                        let handle_time = Instant::now();

                        // 设置超时时间
                        if config_new.write_timeout > 0 {
                            stream.set_write_timeout(Some(Duration::from_secs(config_new.write_timeout))).unwrap_or_default();
                        }
                        if config_new.read_timeout > 0 {
                            stream.set_read_timeout(Some(Duration::from_secs(config_new.read_timeout))).unwrap_or_default();
                        }

                        // 获取请求客户端IP
                        let client_ip = stream.peer_addr().unwrap().ip().to_string();
                        // 获取服务端IP
                        let server_ip = stream.local_addr().unwrap().ip().to_string();


                        let mut scheme = if config_new.https {
                            match acceptor_new.accept(stream.try_clone().unwrap()) {
                                Ok(e) => Scheme::Https(Arc::new(Mutex::new(e)), client_ip.clone()),
                                Err(_) => return Err(Error::other("加载加密请求失败")),
                            }
                        } else {
                            Scheme::Http(Arc::new(Mutex::new(stream.try_clone().unwrap())), client_ip.clone())
                        };

                        let mut request = Request::default(config_new.clone(), handle_time);
                        let mut response = Response::default(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));

                        let mut bytes = vec![];
                        //  请求行处理
                        scheme.request_line(&mut bytes, &mut request)?;

                        match request.protocol {
                            Protocol::HTTP1_0 | Protocol::HTTP1_1 => {
                                scheme.request_header(&mut bytes, &mut request)?;
                                scheme.request_body(&mut bytes, &mut request)?;
                                request.handle(&server_ip, &client_ip);

                                response.set_request(&mut request);

                                match request.upgrade {
                                    Upgrade::Websocket => {
                                        let mut websocket = Websocket::new(request.clone(), response.clone());
                                        if let Ok(()) = websocket.handle(factory) {}
                                        if USERS.get(&websocket.key.to_string()).is_some() {
                                            USERS.remove(&websocket.key);
                                        }
                                        if response.config.debug {
                                            let len = USERS.len();
                                            info!("退出: {len}");
                                        }
                                    }
                                    Upgrade::Http => {
                                        match request.method {
                                            Method::OPTIONS => {
                                                let websocket = Websocket::new(request.clone(), response.clone());
                                                factory(websocket).on_options(&mut response);
                                                response.send()?;
                                            }
                                            _ => {
                                                if let Ok(e) = request.read_resource() { response.status(200).file(&e).send()? } else {
                                                    let websocket = Websocket::new(request.clone(), response.clone());
                                                    let mut factory_new = factory(websocket);
                                                    factory_new.on_request(request.clone(), &mut response);
                                                    factory_new.on_response(request.clone(), &mut response);
                                                    response.send()?;
                                                }
                                            }
                                        }
                                    }
                                    Upgrade::None => {
                                        response.status(404).send()?;
                                    }
                                }
                            }
                            Protocol::HTTP2 => {
                                let websocket = Websocket::new(request.clone(), response.clone());
                                scheme.http2_handle(&mut bytes, &mut request, &mut response, &server_ip, &client_ip)?;
                                let mut factory_new = factory(websocket);
                                factory_new.on_request(request.clone(), &mut response);
                                factory_new.on_response(request.clone(), &mut response);
                                scheme.send_http2(&mut response)?;
                                //loop {
                                //    scheme.http2_handle(&mut bytes, &mut request, &mut response, &server_ip, &client_ip)?;
                                //    let mut factory_new = factory(websocket);
                                //    factory_new.on_request(request.clone(), &mut response);
                                //    factory_new.on_response(request.clone(), &mut response);
                                //    scheme.send_http2(&mut response)?;
                                //    break;
                                //}
                            }
                            Protocol::None => {
                                return Err(Error::other("未知请求"));
                            }
                        }

                        // 日志记录
                        match request.save_log() {
                            Ok(()) => {}
                            Err(_) => {
                                error!("日志记录错误");
                            }
                        }
                        Ok(())
                    });
                }
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    fn ssl(config: &Config) -> io::Result<Arc<SslAcceptor>> {
        if config.https {
            let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
            if !config.tls.key.is_file() {
                return Err(Error::other(
                    format!("private.key 不存在: {:?}", config.tls.key).as_str(),
                ));
            }
            if !config.tls.certs.is_file() {
                return Err(Error::other(
                    format!("certificate.pem 不存在: {:?}", config.tls.certs).as_str(),
                ));
            }
            acceptor.set_private_key_file(config.tls.key.clone(), SslFiletype::PEM)?;
            acceptor.set_certificate_file(config.tls.certs.clone(), SslFiletype::PEM)?;
            Ok(Arc::new(acceptor.build()))
        } else {
            Ok(Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls())?.build()))
        }
    }
}

pub trait HandlerClone {
    fn clone_box(&self) -> Box<dyn Handler>;
}

// 实现 HandlerClone for 所有 Handler + Clone 的实现者
impl<T> HandlerClone for T
where
    T: 'static + Handler + Clone,
{
    fn clone_box(&self) -> Box<dyn Handler> {
        Box::new(self.clone())
    }
}

// 为 dyn Handler 实现 Clone
impl Clone for Box<dyn Handler> {
    fn clone(&self) -> Box<dyn Handler> {
        self.clone_box()
    }
}
pub trait Handler: Send + Sync + HandlerClone + Debug {
    /// 请求 处理
    fn on_request(&mut self, _request: Request, _response: &mut Response) {}
    /// 预检请求处理 OPTIONS
    fn on_options(&mut self, response: &mut Response) {
        if !response.headers.has_key("Access-Control-Allow-Origin") {
            response.header("Access-Control-Allow-Origin", "*");
        }
        // GET,POST,OPTIONS
        if !response.headers.has_key("Access-Control-Allow-Methods") {
            response.header("Access-Control-Allow-Methods", "*");
        }
        // Content-Type, Authorization, X-Real-IP,X-Forwarded-For
        if response.headers.has_key("Access-Control-Allow-Headers") {
            let headers = response.headers["Access-Control-Allow-Headers"].to_string();
            response.header("Access-Control-Allow-Headers", format!("Content-Type,Authorization,X-Real-IP,X-Forwarded-For,{headers}").as_str());
        } else {
            response.header("Access-Control-Allow-Headers", "Content-Type,Authorization,X-Real-IP,X-Forwarded-For");
        }
        // 允许前端跨域请求时发送和接收 cookie / 凭据
        if !response.headers.has_key("Access-Control-Expose-Headers") {
            response.header("Access-Control-Expose-Headers", "true");
        }
        // 允许前端访问请求头
        if !response.headers.has_key("Access-Control-Expose-Headers") {
            response.header("Access-Control-Expose-Headers", "Content-Disposition");
        }
        if !response.headers.has_key("Access-Control-Max-Age") {
            response.header("Access-Control-Max-Age", "0");
        }
    }
    /// 响应 处理
    fn on_response(&mut self, request: Request, response: &mut Response) {
        if response.config.origin.is_empty() {
            response.header("Access-Control-Allow-Origin", "*");
        } else {
            let origin = request.header["origin"].as_str().unwrap_or("");
            for item in response.config.origin.clone() {
                if origin.contains(item.as_str()) {
                    response.header("Access-Control-Allow-Origin", origin);
                }
            }
        }
        if response.headers.has_key("Content-Disposition") {
            response.header("Access-Control-Expose-Headers", "Content-Disposition");
        }
    }

    fn on_frame(&mut self) -> io::Result<()> {
        Ok(())
    }
    /// 握手监听
    fn on_open(&mut self) -> io::Result<()> {
        Ok(())
    }
    /// 接收到消息
    fn on_message(&mut self, _msg: Message) -> io::Result<()> {
        Ok(())
    }
    /// 关闭监听
    fn on_close(&mut self, _code: CloseCode, _reason: &str) {}
    /// 错误监听
    fn on_error(&mut self, _err: ErrorCode) {}
    /// 关机监听
    fn on_shutdown(&mut self) {}
    /// ping
    fn on_ping(&mut self, _msg: Message) {}
    /// pong
    fn on_pong(&mut self, _msg: Message) {}
}

