use std::borrow::Cow;
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, Offset, Utc};
use crate::{ContentType, Version};

/// 响应
#[derive(Debug)]
pub struct Response {
    pub content_length: usize,
    pub version: Version,
    pub content_type: ContentType,
    pub status: usize,
    pub date: String,
    pub err: String,
    pub body: String,
    pub location: String,
    pub cookie:String
}

impl Response {
    pub fn default() -> Response {
        Response {
            content_length: 0,
            version: Version::None,
            content_type: ContentType::None,
            status: 0,
            date: "".to_string(),
            err: "".to_string(),
            body: "".to_string(),
            location: "".to_string(),
            cookie: "".to_string(),
        }
    }
    pub fn new(&mut self, data: Cow<str>) -> &mut Self {
        let mut header = true;
        for line in data.lines() {
            if header && line == "" {
                header = false;
                continue;
            }
            match header {
                true => {
                    match self.version {
                        Version::None => {
                            let r = line.split(" ").collect::<Vec<&str>>();
                            self.version = Version::from(r[0]);
                            self.status = r[1].parse::<usize>().unwrap();
                            if r.len() > 2 {
                                self.err = r[2..].concat();
                            }
                            continue;
                        }
                        _ => {}
                    }
                    match line.strip_prefix("Content-Type: ") {
                        None => {}
                        Some(e) => {
                            self.content_type = ContentType::from(e.trim());
                            continue;
                        }
                    }
                    match line.strip_prefix("Content-Length: ") {
                        None => {}
                        Some(e) => {
                            self.content_length = e.parse::<usize>().unwrap();
                            continue;
                        }
                    }
                    match line.strip_prefix("Location: ") {
                        None => {}
                        Some(e) => {
                            self.location = e.to_string();
                            continue;
                        }
                    }
                    match line.strip_prefix("Cookie: ") {
                        None => {}
                        Some(e) => {
                            self.cookie = e.to_string();
                            continue;
                        }
                    }


                    match line.strip_prefix("Date: ") {
                        None => {}
                        Some(datetime) => {
                            let naive_datetime = NaiveDateTime::parse_from_str(datetime, "%a, %d %b %Y %H:%M:%S GMT");
                            let naive_datetime = match naive_datetime {
                                Ok(e) => e,
                                Err(_) => {
                                    continue;
                                }
                            };
                            let datetime_utc: DateTime<Utc> = DateTime::from_naive_utc_and_offset(naive_datetime, Utc);
                            let local_offset = Local::now().offset().fix();
                            let datetime_local: DateTime<FixedOffset> = datetime_utc.with_timezone(&local_offset);
                            self.date = datetime_local.format("%Y-%m-%d %H:%M:%S").to_string();
                            continue;
                        }
                    }
                }
                false => {
                    if self.content_length > self.body.len() {
                        self.body.push_str(line);
                    }
                }
            }
        }
        self
    }
}