pub mod address;
pub mod error;
pub mod router_pattern;
mod raw;
mod domain;
mod proxy_entry_setting;

use crate::config::proxy_entry_setting::ProxyEntrySetting;
use crate::config::router_pattern::RouterPattern;
use crate::{
    argument::Argument,
    config::{error::Error, raw::raw_config::RawConfig},
};
use std::path::PathBuf;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Config {
    port: u16,
    enable_tls: bool,
    cert_path: Option<PathBuf>,
    key_path: Option<PathBuf>,
    proxies: Vec<(RouterPattern, ProxyEntrySetting)>,
}

impl Config {
    pub fn port(&self) -> &u16 {
        &self.port
    }

    pub fn tls_config(&self) -> Option<(PathBuf, PathBuf)> {
        if !self.enable_tls {
            return None;
        }

        if let Some (cert_path) = &self.cert_path &&
            let Some(key_path) = &self.key_path {
            return Some((cert_path.clone(), key_path.clone()));
        }

        None
    }

    pub fn proxies(&self) -> impl Iterator<Item = &(RouterPattern, ProxyEntrySetting)> {
        self.proxies.iter()
    }
}

pub fn parse(arg: &Argument) -> Result<Config> {
    RawConfig::with_argument(arg).try_into()
}
