use crate::stream::{Protocol};
use crate::request::{Request};
use chrono::{DateTime, Duration as dur, Utc};
use json::{object, JsonValue};
use log::{error, info};
use std::path::{Path, PathBuf};
use std::{fs, io, thread};
use std::io::Error;
use hpack::Encoder;
use crate::{ContentType, Encoding, Handler, HttpError, Method, Upgrade};
use crate::websocket::Websocket;
const FLAG_END_STREAM: u8 = 0x01;
const FLAG_END_HEADERS: u8 = 0x04;
/// 响应
#[derive(Clone, Debug)]
pub struct Response {
    pub request: Request,
    pub status: Status,
    pub headers: JsonValue,
    pub cookies: JsonValue,
    /// 消息体
    pub body: Vec<u8>,
    /// HTTP2 使用
    pub stream_id: u32,
    /// ws 通信密钥
    pub key: String,
    /// ws 版本
    pub version: String,
    pub factory: fn(out: Websocket) -> Box<dyn Handler>,
    /// 允许来源
    pub allow_origins: Vec<&'static str>,
    /// 允许方法
    pub allow_methods: Vec<&'static str>,
    /// 允许请求头
    pub allow_headers: Vec<&'static str>,
    /// 消息体类型
    pub content_type: ContentType,
}
impl Response {
    pub fn new(request: Request, factory: fn(out: Websocket) -> Box<dyn Handler>) -> Self {
        Self {
            request: request.clone(),
            status: Status::default(),
            headers: object! {},
            cookies: object! {},
            body: vec![],
            stream_id: 0,
            key: String::new(),
            version: String::new(),
            factory,
            allow_origins: vec![],
            allow_methods: vec![],
            allow_headers: vec![],
            content_type: ContentType::Other(String::new()),
        }
    }
    pub fn handle(mut self) -> io::Result<()> {
        if let Upgrade::Websocket = self.request.upgrade {
            self.handle_protocol_ws()?;
            return Ok(());
        }

        match self.request.protocol {
            Protocol::HTTP1_0 => self.handle_protocol_http0()?,
            Protocol::HTTP1_1 => self.handle_protocol_http1()?,
            Protocol::HTTP2 => self.handle_protocol_http2()?,
            Protocol::HTTP3 => {}
            Protocol::Other(_) => {}
        }
        Ok(())
    }
    fn handle_protocol_http0(&mut self) -> io::Result<()> {
        let websocket = Websocket::http(self.request.clone(), self.clone());
        let mut factory = (self.factory)(websocket);
        match self.request.method {
            Method::OPTIONS => {
                factory.on_options(self);
                match self.on_options() {
                    Ok(_) => {
                        match self.status(200).send() {
                            Ok(_) => {}
                            Err(e) => return Err(Error::other(format!("1004: {} {} {}", self.request.uri.path, e.code, e.body))),
                        };
                    }
                    Err(e) => return {
                        self.status(e.code).txt(e.body.as_str()).send().unwrap();
                        Ok(())
                    }
                };
            }
            Method::GET => {
                if let Ok(e) = self.read_resource() {
                    return match self.status(200).file(&e).send() {
                        Ok(_) => Ok(()),
                        Err(e) => Err(Error::other(format!("1003: {} {} {}", self.request.uri.path, e.code, e.body))),
                    };
                }
                factory.on_request(self.request.clone(), self);
                factory.on_response(self);
                match self.send() {
                    Ok(_) => {}
                    Err(e) => return Err(Error::other(format!("1002: {} {} {}", self.request.uri.path, e.code, e.body))),
                }
            }
            _ => {
                factory.on_request(self.request.clone(), self);
                factory.on_response(self);
                match self.send() {
                    Ok(_) => {}
                    Err(e) => return Err(Error::other(format!("1001: {} {}", e.code, e.body))),
                }
            }
        }
        Ok(())
    }
    fn handle_protocol_http1(&mut self) -> io::Result<()> {
        self.handle_protocol_http0()
    }
    fn handle_protocol_http2(&mut self) -> io::Result<()> {
        let websocket = Websocket::http(self.request.clone(), self.clone());
        let mut factory = (self.factory)(websocket);
        match self.request.method {
            Method::OPTIONS => {
                factory.on_options(self);
                match self.send() {
                    Ok(_) => {}
                    Err(e) => return Err(Error::other(format!("2001: {} {}", e.code, e.body))),
                };
            }
            Method::GET => {
                if let Ok(e) = self.read_resource() {
                    return match self.status(200).file(&e).send() {
                        Ok(_) => Ok(()),
                        Err(e) => Err(Error::other(e.body)),
                    };
                }
                factory.on_request(self.request.clone(), self);
                factory.on_response(self);
                match self.send() {
                    Ok(_) => {}
                    Err(e) => return Err(Error::other(format!("2002: {} {}", e.code, e.body))),
                }
            }
            _ => {
                factory.on_request(self.request.clone(), self);
                factory.on_response(self);
                match self.send() {
                    Ok(_) => {}
                    Err(e) => return Err(Error::other(format!("2003: {} {}", e.code, e.body))),
                }
            }
        }
        Ok(())
    }
    fn handle_protocol_ws(&mut self) -> io::Result<()> {
        let mut websocket = Websocket::new(self.request.clone(), self.clone());
        let _ = websocket.handle();
        Ok(())
    }
    /// 读取资源文件
    fn read_resource(&mut self) -> io::Result<PathBuf> {
        if self.request.uri.path != "/" {
            let file = self.request.config.root_path.join(self.request.config.public.clone()).join(self.request.uri.path.trim_start_matches('/'));
            if file.is_file() {
                return Ok(file);
            }
        }
        if self.request.uri.path == "/" {
            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join("index.html");
            if file.is_file() {
                return Ok(file);
            }
        } else {
            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join(self.request.uri.path.trim_start_matches('/'));
            if file.is_file() {
                return Ok(file);
            }
        }
        Err(Error::other("Not a file"))
    }
    pub fn status(&mut self, code: u16) -> &mut Self {
        self.status.set_code(code);
        self
    }
    /// 跳转
    pub fn location(&mut self, uri: &str) -> &mut Self {
        self.header("Location", uri);
        self
    }
    /// 设置 HOST
    pub fn set_host(&mut self, host: &str) -> &mut Self {
        self.header("Host", host);
        self
    }

    pub fn header(&mut self, key: &str, value: &str) -> &mut Self {
        self.headers[key] = value.into();
        self
    }
    pub fn cookie(&mut self, key: &str, value: &str) -> &mut Self {
        self.cookies[key] = value.into();
        self
    }
    fn get_date(&self, s: i64) -> String {
        let utc: DateTime<Utc> = Utc::now();
        let future = utc + dur::seconds(s); // 加 3600 秒 = 1 小时
        future.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
    }
    /// HTML 返回
    pub fn html(&mut self, value: &str) -> &mut Self {
        if self.request.config.charset.is_empty() {
            self.header("Content-Type", format!("{};", Extension::form("html").as_str()).as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form("html").as_str(), self.request.config.charset).as_str());
        }
        self.content_type = ContentType::Html;
        self.body = value.as_bytes().to_vec();
        self
    }
    /// TXT 返回
    pub fn txt(&mut self, value: &str) -> &mut Self {
        if self.request.config.charset.is_empty() {
            self.header("Content-Type", Extension::form("txt").as_str().to_string().as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form("txt").as_str(), self.request.config.charset).as_str());
        }
        self.content_type = ContentType::Text;
        self.body = value.as_bytes().to_vec();
        self
    }
    /// JSON 返回
    pub fn json(&mut self, value: JsonValue) -> &mut Self {
        if self.request.config.charset.is_empty() {
            self.header("Content-Type", Extension::form("json").as_str().to_string().as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form("json").as_str(), self.request.config.charset).as_str());
        }
        self.content_type = ContentType::Json;
        self.body = value.to_string().into_bytes();
        self
    }
    /// 下载 返回
    ///
    /// # Panics
    ///
    /// This function will panic if:
    /// - `filename.extension()` returns `None`
    /// - The extension cannot be converted to a valid UTF-8 string
    /// - The filename cannot be converted to a valid UTF-8 string
    pub fn download(&mut self, filename: &Path) -> &mut Self {
        let Ok(file) = fs::read(filename) else {
            self.status(404);
            return self;
        };
        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();

        if self.request.config.charset.is_empty() {
            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
        }

        let encoded_file_name = br_crypto::encoding::urlencoding_encode(filename.file_name().unwrap().to_str().unwrap());
        self.header("Content-Disposition", format!(r"attachment; filename={encoded_file_name}").as_str());
        self.header("Cache-Control", "no-cache");
        self.header("ETag", br_crypto::md5::encrypt_hex(&file).as_str());
        self.body = file;
        self
    }
    /// 分片
    pub fn range(&mut self, range: &str, filename: &Path) -> &mut Self {
        let Ok(file) = fs::read(filename) else {
            self.status(404);
            return self;
        };
        let range = range.trim_start_matches("bytes=");
        let range = range.split("-").collect::<Vec<&str>>();
        let range_start = range[0].parse::<usize>().unwrap();
        let range_end = range[1].parse::<usize>().unwrap();

        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();

        if self.request.config.charset.is_empty() {
            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
        }

        self.header("Accept-Ranges", "bytes");
        self.header("content-length", (range_end - range_start + 1).to_string().as_str());
        self.header("Content-Range", format!("bytes {}-{}/{}", range_start, range_end, file.len()).as_str());
        self.body = file[range_start..=range_end].to_vec();
        self
    }
    /// Serves a file for inline display in the browser.
    ///
    /// # Panics
    ///
    /// This function will panic if the file extension cannot be converted to a string,
    /// or if the filename cannot be converted to a valid UTF-8 string.
    pub fn file(&mut self, filename: &Path) -> &mut Self {
        let Ok(file) = fs::read(filename) else {
            self.status(404);
            return self;
        };

        let extension = match filename.extension() {
            None => String::new(),
            Some(e) => e.to_str().unwrap().to_lowercase(),
        };
        if self.request.config.charset.is_empty() {
            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
        } else {
            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
        }
        self.header("Content-Disposition", format!(r#"inline; filename="{}""#, filename.file_name().unwrap().to_str().unwrap()).as_str());
        //let digest = md5::compute(file.clone());
        //self.header("Cache-Control", "no-cache");
        //self.header("ETag", format!("{digest:x}").as_str());
        self.header("Cache-Control", format!("public, max-age={}", 1800).as_str());
        self.header("Expires", &self.clone().get_date(1800));
        //if self.config.max_age > 0 {
        //    self.header("Cache-Control", format!("public, max-age={}", self.config.max_age).as_str());
        //    self.header("Expires", &self.clone().get_date(self.config.max_age));
        //} else {
        //    self.header("Cache-Control", "no-cache");
        //}

        self.body = file;
        self
    }
    /// Sends the response over the given scheme.
    ///
    /// # Errors
    ///
    /// Returns an error if writing the response over the scheme fails.
    pub fn send(&mut self) -> Result<(), HttpError> {
        match &self.request.protocol {
            Protocol::HTTP1_0 | Protocol::HTTP1_1 => Ok(self.send_http1()?),
            Protocol::HTTP2 => Ok(self.send_http2()?),
            Protocol::HTTP3 => {
                error!("Other1:{:?} {:?}", thread::current().id(),self.request);
                Err(HttpError::new(500, "暂未实现HTTP3"))
            }
            Protocol::Other(e) => {
                error!("Other:{:?} {:?}", thread::current().id(),self.request);
                Err(HttpError::new(500, format!("暂未实现Other: {} {} {:?}", e, self.request.uri.path, thread::current().id()).as_str()))
            }
        }
    }
    fn send_http1(&mut self) -> Result<(), HttpError> {
        let mut header = vec![];
        header.push(format!("{} {} {}", self.request.protocol.str(), self.status.code, self.status.reason));
        self.header("Date", &self.get_date(0));

        match self.request.method {
            Method::HEAD => {
                self.header("Content-Length", self.body.len().to_string().as_str());
                self.body = vec![];
            }
            Method::OPTIONS => {
                self.header("Content-Length", "0");
                self.body = vec![];
            }
            _ => {
                match self.request.accept_encoding {
                    Encoding::Gzip => {
                        self.header("Content-Encoding", self.request.accept_encoding.clone().str());
                        if let Ok(e) = self.request.accept_encoding.clone().compress(&self.body.clone()) { self.body = e };
                        self.header("Content-Length", self.body.len().to_string().as_str());
                    }
                    _ => { self.header("Content-Length", self.body.len().to_string().as_str()); }
                }
            }
        };

        for (key, value) in self.headers.entries() {
            header.push(format!("{key}: {value}"));
        }

        for (key, value) in self.cookies.entries() {
            header.push(format!("Set-Cookie: {key}={value}; Path=/; HttpOnly; SameSite=Lax"));
        }

        if self.request.config.debug {
            info!("\r\n=================响应信息 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),header.join("\r\n"));
            match self.request.accept_encoding {
                Encoding::Gzip => {}
                _ => {
                    match self.content_type {
                        ContentType::Text | ContentType::Html | ContentType::Json | ContentType::FormUrlencoded => {
                            info!("\r\n=================响应体 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),String::from_utf8_lossy(self.body.as_slice()));
                        }
                        _ => {}
                    };
                }
            }
        }
        let mut headers = format!("{}\r\n\r\n", header.join("\r\n")).into_bytes();
        headers.extend(self.body.clone());
        self.request.scheme.lock().unwrap().write(headers.as_slice())?;
        Ok(())
    }
    fn send_http2(&mut self) -> Result<(), HttpError> {
        let max_frame_size: usize = 16_384;
        let stream_id = 1u32;
        // 先构建所有帧，避免持锁期间借用 self
        let header_frames = self.http2_header(stream_id, max_frame_size);
        // 如果 header 已经 END_STREAM（即没有 body），这里会返回空 Vec
        let data_frames = self.http2_body(stream_id, true, max_frame_size);

        // 仅锁一次写端，顺序写出所有帧
        let mut writer = self.request.scheme.lock().unwrap();
        for f in header_frames { writer.write(&f)?; }
        for f in data_frames { writer.write(&f)?; }

        //let header_data = self.http2_header(stream_id,max_frame_size);
        //for header in header_data {
        //    self.request.scheme.lock().unwrap().write(header.as_slice())?;
        //    let data_frame = self.http2_body(stream_id, true);
        //    self.request.scheme.lock().unwrap().write(data_frame.as_slice())?;
        //}
        Ok(())
    }

    fn http2_header(&mut self, stream_id: u32, max_frame_size: usize) -> Vec<Vec<u8>> {
        let mut encoder = Encoder::new();

        let mut headers: Vec<(Vec<u8>, Vec<u8>)> = vec![
            (b":status".to_vec(), self.status.code.to_string().into_bytes()),
            (b"date".to_vec(), self.get_date(0).into_bytes()),
        ];

        match self.request.method {
            Method::HEAD => {
                self.header("content-length", self.body.len().to_string().as_str());
                self.body.clear(); // HEAD 响应不携带实体
            }
            Method::OPTIONS => {
                self.header("content-length", self.body.len().to_string().as_str());
                self.body.clear();
            }
            _ => {
                self.header("content-length", self.body.len().to_string().as_str());
            }
        }

        headers.extend(
            self.headers.entries().map(|(k, v)| (k.to_string().to_lowercase().into_bytes(), v.to_string().into_bytes()))
        );
        headers.extend(
            self.cookies.entries().map(|(k, v)| (b"set-cookie".to_vec(), format!("{k}={v}; Path=/; HttpOnly; SameSite=Lax").into_bytes()))
        );

        if self.request.config.debug {
            let dbg = headers.iter().map(|(n, v)| {
                format!("{}: {}", String::from_utf8_lossy(n), String::from_utf8_lossy(v))
            }).collect::<Vec<_>>().join("\r\n");
            info!("\n=================响应信息 {:?}=================\n{}\n===========================================",
              std::thread::current().id(), dbg);
        }

        // 2) HPACK 编码
        let block = encoder.encode(headers.iter().map(|h| (&h.0[..], &h.1[..])));

        // 3) 拆分为 HEADERS + CONTINUATION...；如果 body 为空，需要在最后一块加 END_STREAM
        let end_stream = self.body.is_empty();
        let mut frames = Vec::new();
        let mut remaining = block.as_slice();
        let mut first = true;

        while !remaining.is_empty() {
            let take = remaining.len().min(max_frame_size);
            let (chunk, rest) = remaining.split_at(take);
            remaining = rest;

            let is_last = remaining.is_empty();
            let mut flags = 0u8;
            if is_last { flags |= FLAG_END_HEADERS; }
            if is_last && end_stream { flags |= FLAG_END_STREAM; }

            // 9字节帧头
            let mut f = Vec::with_capacity(9 + chunk.len());
            let len = chunk.len();
            f.push(((len >> 16) & 0xFF) as u8);
            f.push(((len >> 8) & 0xFF) as u8);
            f.push((len & 0xFF) as u8);
            f.push(if first { 0x01 } else { 0x09 }); // HEADERS / CONTINUATION
            f.push(flags);
            f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
            f.extend_from_slice(chunk);

            frames.push(f);
            first = false;
        }

        // 如果 block 为空（极少见），也要至少发一个空 HEADERS（END_HEADERS [+END_STREAM]）
        if frames.is_empty() {
            let mut f = vec![0, 0, 0, 0x01, FLAG_END_HEADERS | if end_stream { FLAG_END_STREAM } else { 0 }, 0, 0, 0, 0];
            f[5..9].copy_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
            frames.push(f);
        }

        frames
    }
    fn http2_body(&mut self, stream_id: u32, end_stream: bool, max_frame_size: usize) -> Vec<Vec<u8>> {
        // 取走 body，避免重复发送
        let body = std::mem::take(&mut self.body);

        // body 为空：如果需要结束流，发一帧空 DATA+END_STREAM；否则不发
        if body.is_empty() {
            return if end_stream {
                vec![self.build_data_frame(stream_id, &[], true)]
            } else {
                Vec::new()
            };
        }

        let mut frames = Vec::new();
        let mut off = 0usize;
        let total = body.len();

        while off < total {
            let take = (total - off).min(max_frame_size);
            let chunk = &body[off..off + take];
            off += take;

            let last = off == total;
            frames.push(self.build_data_frame(stream_id, chunk, last && end_stream));
        }
        frames
    }
    fn build_data_frame(&self, stream_id: u32, payload: &[u8], end_stream: bool) -> Vec<u8> {
        let len = payload.len();
        let mut f = Vec::with_capacity(9 + len);
        f.push(((len >> 16) & 0xFF) as u8);
        f.push(((len >> 8) & 0xFF) as u8);
        f.push((len & 0xFF) as u8);
        f.push(0x00); // DATA
        f.push(if end_stream { FLAG_END_STREAM } else { 0 });
        f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
        if !payload.is_empty() { f.extend_from_slice(payload); }
        f
    }
    fn on_options(&mut self) -> Result<(), HttpError> {
        if self.allow_origins.is_empty() {
            self.header("Access-Control-Allow-Origin", "*");
        } else if self.request.header.has_key("origin") {
            if self.allow_origins.contains(&self.request.origin.as_str()) {
                self.header("Access-Control-Allow-Origin", self.request.origin.to_string().as_str());
            } else {
                return Err(HttpError::new(403, "Origin not allowed"));
            }
        } else {
            return Err(HttpError::new(403, "Origin not allowed"));
        }

        if self.allow_headers.is_empty() {
            if !self.request.header.has_key("access-control-request-headers") {
                return Err(HttpError::new(403, "headers not allowed"));
            }
            self.header("Access-Control-Allow-Headers", self.request.header["access-control-request-headers"].to_string().as_str());
        } else if !self.request.header.has_key("access-control-request-headers") {
            let headers = self.allow_headers.join(",");
            self.header("Access-Control-Allow-Headers", headers.to_string().as_str());
        } else {
            let headers = self.allow_headers.join(",");
            self.header("Access-Control-Allow-Headers", format!("{},{}", self.request.header["access-control-request-headers"], headers).as_str());
        }

        if self.allow_methods.is_empty() {
            if !self.request.header.has_key("access-control-request-method") {
                return Err(HttpError::new(403, "methods not allowed"));
            }
            self.header("Access-Control-Allow-Methods", self.request.header["access-control-request-method"].to_string().as_str());
        } else {
            let methods = self.allow_methods.join(",");
            self.header("Access-Control-Allow-Methods", methods.to_string().as_str());
        }
        self.header("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
        Ok(())
    }
}
#[derive(Clone, Debug)]
pub struct Status {
    pub code: u16,
    reason: String,
}
impl Status {
    pub fn set_code(&mut self, code: u16) {
        self.code = code;
        self.reason = match code {
            100 => "Continue", // 服务器愿意接收请求实体（配合 Expect: 100-continue）。
            101 => "Switching Protocols", // 协议切换（如升级到 WebSocket）。
            102 => "Processing",
            103 => "Early Hints", // 提前提示可预加载的资源。
            200 => "OK", // 请求成功（GET/PUT/PATCH 通用）
            201 => "Created", // 已创建新资源（典型于 POST）
            202 => "Accepted", // 已接受处理但未完成（异步任务）。
            204 => "No Content", // 成功但无响应体（DELETE 常用）。
            206 => "Partial Content", // 部分内容（Range 下载）。
            301 => "Moved Permanently", // 永久重定向
            302 => "Found", // 临时重定向（历史上易与 303/307混用）。
            303 => "See Other", // 告诉客户端去 GET 另一个 URI（表单提交后跳详情页）。
            304 => "Not Modified", // 资源未变更（配合缓存 ETag/Last-Modified）。
            307 => "Temporary Redirect", // 临时，不改变方法（POST 仍是 POST）
            308 => "Permanent Redirect", // 永久，不改变方法。

            400 => "Bad Request", // 请求报文有误/语法错误/JSON 无法解析/缺少必需字段或头。
            401 => "Unauthorized", // 未认证或凭证无效（要带 WWW-Authenticate）。
            403 => "Forbidden",
            404 => "Not Found", //服务器无法根据客户端的请求找到资源（网页）。通过此代码，网站设计人员可设置"您所请求的资源无法找到"的个性页面
            405 => "Method Not Allowed", // 方法不被允许（应返回 Allow 头）。
            411 => "Length Required", // 缺少 Content-Length。
            413 => "Payload Too Large", // 请求体过大。
            414 => "URI Too Long", // URI 太长。
            429 => "Too Many Requests", // 限流
            431 => "Request Header Fields Too Large", // 请求头过大。

            500 => "Internal Server Error", //服务器内部错误，无法完成请求
            501 => "Not Implemented", //服务器不支持请求的功能，无法完成请求
            502 => "Bad Gateway", //作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应
            503 => "Service Unavailable", //服务不可用/维护中（可带 Retry-After）。
            504 => "Gateway Time-out",    //网关超时（上游响应超时）。
            505 => "HTTP Version Not Supported", //服务器不支持请求的HTTP协议的版本，无法完成处理
            _ => "",
        }.to_string();
    }
}
impl Default for Status {
    fn default() -> Self {
        Self {
            code: 200,
            reason: "OK".to_string(),
        }
    }
}

/// 文件类型
enum Extension {}
impl Extension {
    pub fn form(extension: &str) -> String {
        match extension {
            "html" => "text/html",
            "css" => "text/css",
            "js" => "application/javascript",
            "json" => "application/json",
            "png" => "image/png",

            "jpg" | "jpeg" => "image/jpeg",
            "gif" => "image/gif",
            "txt" => "text/plain",
            "pdf" => "application/pdf",
            "svg" => "image/svg+xml",
            "woff" => "application/font-woff",
            "woff2" => "application/font-woff2",
            "xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            _ => "application/octet-stream",
        }.to_string()
    }
}


