use std::io::{Error};
use br_crypto::hash::{u8_to_md5};
use crate::{Receive, Sender};
use crate::imap::server::Server;

mod server;

#[derive(Clone, Debug)]
pub struct Imap {
    /// 邮件地址
    host: String,
    /// 邮件端口
    port: u16,
    /// 邮件名称
    name: String,
    /// 邮件账号
    mail: String,
    /// 邮件密码
    pass: String,
}

impl Imap {
    pub fn new(host: String, port: u16, name: String, mail: String, pass: String) -> Self {
        Self {
            host,
            port,
            name,
            mail,
            pass,
        }
    }
    fn login(&mut self) -> Result<Server, Error> {
        let mut conn = Server::new(self.host.clone(), self.port.clone())?;
        conn.login(self.mail.clone(), self.pass.clone())?;
        Ok(conn)
    }
}


impl Receive for Imap {
    /// 获取邮件总数
    fn get_total(&mut self) -> Result<usize, Error> {
        let mut conn = self.login()?;
        let r = conn.total()?;
        Ok(r)
    }

    fn get_id_list(&mut self) -> Result<Vec<String>, Error> {
        let mut conn = self.login()?;
        let r = conn.select()?;
        Ok(r)
    }

    fn get_id_info(&mut self, id: &str) -> Result<(Vec<u8>, usize, String), Error> {
        let mut conn = self.login()?;
        let r = conn.info(id)?;
        let body = r[..r.len()].to_vec();
        Ok((body.clone(), body.len(), u8_to_md5(body).leak().to_string()))
    }

    fn del_id(&mut self, id: &str) -> Result<bool, Error> {
        let mut conn = self.login()?;
        let r = conn.delete(id)?;
        Ok(r)
    }
}

impl Sender for Imap {
    fn send(&mut self) -> Result<(Vec<u8>, usize, String), std::io::Error> {
        todo!()
    }

    fn set_from(&mut self, _name: &str) -> &mut dyn Sender {
        todo!()
    }

    fn set_to(&mut self, _name: &str, _mail: &str) -> &mut dyn Sender {
        todo!()
    }

    fn set_cc(&mut self, _name: &str, _mail: &str) -> &mut dyn Sender {
        todo!()
    }

    fn set_subject(&mut self, _subject: &str) -> &mut dyn Sender {
        todo!()
    }

    fn set_body(&mut self, _text: &str, _html: &str) -> &mut dyn Sender {
        todo!()
    }

    fn set_file(&mut self, _name: &str, _data: Vec<u8>, _content_type: &str) -> &mut dyn Sender {
        todo!()
    }
}