use crate::models::{ComponentStatus, Profile, Target};

#[derive(Debug, Clone, Copy)]
pub struct ProxyRouterRequest<'a> {
    pub profiles: &'a [Profile],
    pub targets: &'a [Target],
    pub components: &'a [ComponentStatus],
}

impl<'a> ProxyRouterRequest<'a> {
    pub fn new(
        profiles: &'a [Profile],
        targets: &'a [Target],
        components: &'a [ComponentStatus],
    ) -> Self {
        Self {
            profiles,
            targets,
            components,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProxyRouterGeneratedConfig {
    pub adapter_id: String,
    pub output_file_name: String,
    pub contents: String,
    pub enabled_profiles: usize,
    pub routed_apps: usize,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProxyRouterError {
    pub kind: ProxyRouterErrorKind,
    pub message: String,
}

impl ProxyRouterError {
    pub fn new(kind: ProxyRouterErrorKind, message: impl Into<String>) -> Self {
        Self {
            kind,
            message: message.into(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProxyRouterErrorKind {
    EmptyProfileItems,
    MissingTarget,
    MissingRequiredComponent,
    RequiredComponentNotRunning,
    UnsupportedTargetProtocol,
    Serialization,
}

pub trait ProxyRouterAdapter {
    fn id(&self) -> &'static str;

    fn output_file_name(&self) -> &'static str;

    fn generate_config(
        &self,
        request: ProxyRouterRequest<'_>,
    ) -> Result<ProxyRouterGeneratedConfig, ProxyRouterError>;
}
