mod implementation;
pub use self::implementation::*;

mod autoconnect;
pub use self::autoconnect::start_autoconnect_server_async;

use std::fmt::Display;

use crate::model::*;

use std::io;

pub trait ClientConnection: Display {}

pub trait ProtocolHandler: Send + Sync + Clone {
    fn new_connection(&mut self, _con: &ClientConnection) {}

    fn query(&mut self, con: &ClientConnection, query: &[String]) -> ProtocolResult<Vec<Texture>>;

    fn get_texture_by_id(
        &mut self,
        con: &ClientConnection,
        id: &str,
    ) -> ProtocolResult<Option<Texture>>;

    fn get_texture_by_name(
        &mut self,
        con: &ClientConnection,
        name: &str,
    ) -> ProtocolResult<Option<Texture>>;

    fn get_texture_file(&mut self, con: &ClientConnection, hash: Sha256)
        -> ProtocolResult<Vec<u8>>;

    fn get_texture_preview(
        &mut self,
        con: &ClientConnection,
        hash: Sha256,
        format: TextureFormat,
    ) -> ProtocolResult<Vec<u8>>;

    fn replace_texture(
        &mut self,
        con: &ClientConnection,
        delete: Option<Texture>,
        insert: Option<Texture>,
        insert_texture_data: Option<Vec<u8>>,
    ) -> ProtocolResult<ReplaceTextureStatus>;

    fn disconnected(&mut self, _con: &ClientConnection) {}
}

#[derive(Clone, Debug)]
pub struct ProtocolConfig {
    pub port: u16,
    pub read_timeout_s: u64,
    pub write_timeout_s: u64,
    pub listen_addr: String,
    pub autoconnect_multicastv6_addr: String,
}

impl ProtocolConfig {
    pub fn new() -> ProtocolConfig {
        ProtocolConfig::default()
    }
}

impl Default for ProtocolConfig {
    fn default() -> ProtocolConfig {
        ProtocolConfig {
            port: 10796,
            read_timeout_s: 60,
            write_timeout_s: 75,
            listen_addr: "::".to_owned(),
            autoconnect_multicastv6_addr: "ff02::dd42:c0fe".to_owned(),
        }
    }
}
