use std::{fmt::Debug, sync::Arc};
use oxinat_derive::uri_builder_alias;
use crate::{UriBuilder, Version};
uri_builder_alias!(SysUriBuilder);
ImplSysUriBuilder! {
    (String),
    (AllowUriBuilder<'_>),
    (CatalogsUriBuilder<'_>),
    (DownloadUriBuilder<'_>),
    (MessagesUriBuilder<'_>),
    (RefreshUriBuilder<'_>),
    (NotifyUriBuilder<'_>),
    (SubscribersUriBuilder<'_>),
}
ImplSysUriBuilder! {
    (ArchiveUriBuilder<Parent>, Parent),
    (AsyncOpsUriBuilder<Parent>, Parent),
    (NotificationsUriBuilder<Parent>, Parent),
    (XnatTaskUriBuilder<Parent>, Parent),
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/archive")]
pub struct ArchiveUriBuilder<Parent>
where
    Parent: SysUriBuilder,
{
    #[parent]
    parent: Option<Arc<Parent>>,
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/catalogs")]
pub struct CatalogsUriBuilder<'a>
{
    #[parent]
    parent: Option<&'a ArchiveUriBuilder<String>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/refresh")]
#[match_path(path = "{parent}/refresh/{operations}")]
pub struct RefreshUriBuilder<'a>
{
    #[param(map_from=r#"|o: &Vec<_>| o.join(",")"#)]
    operations: Option<Vec<String>>,
    #[parent]
    parent: Option<&'a CatalogsUriBuilder<'a>>,
}
impl CatalogsUriBuilder<'_>
{
    pub fn refresh(&self) -> RefreshUriBuilder {
        RefreshUriBuilder::from_parent(&Arc::new(self))
    }
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/download")]
#[match_path(path = "{parent}/download/{catalog_id}")]
pub struct DownloadUriBuilder<'a>
{
    #[param]
    catalog_id: Option<String>,
    #[parent]
    parent: Option<&'a ArchiveUriBuilder<String>>
}
impl DownloadUriBuilder<'_>
{
    pub fn build_test(&self) -> crate::BuildResult {
        self.build_join("test")
    }
    pub fn build_with_size(&self) -> crate::BuildResult {
        self.parent.as_ref().unwrap().build_join("downloadwithsize")
    }
    pub fn build_xml(&self) -> crate::BuildResult {
        self.build_join("xml")
    }
    pub fn build_zip(&self) -> crate::BuildResult {
        self.build_join("zip")
    }
}
impl ArchiveUriBuilder<String>
{
    pub fn catalogs(&self) -> CatalogsUriBuilder {
        CatalogsUriBuilder::from_parent(&Arc::new(self))
    }
    pub fn download(&self) -> DownloadUriBuilder {
        DownloadUriBuilder::from_parent(&Arc::new(self))
    }
    pub fn build_upload_xml(&self) -> crate::BuildResult {
        self.build_join("upload/xml")
    }
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/notifications")]
pub struct NotificationsUriBuilder<Parent>
where
    Parent: SysUriBuilder,
{
    #[parent]
    parent: Option<Arc<Parent>>
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/allow/{name}")]
#[match_path(path = "{parent}/allow/{name}/{setting}")]
pub struct AllowUriBuilder<'a>
{
    #[param]
    name: Option<String>,
    #[param]
    setting: Option<String>,
    #[parent]
    parent: Option<&'a NotificationsUriBuilder<String>>,
}
#[derive(Clone, Debug, UriBuilder)]
pub enum MessageType {
    ForgotUserName,
    Help,
    PasswordReset,
    Registration,
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/messages/{message_type}")]
pub struct MessagesUriBuilder<'a>
{
    #[param]
    message_type: Option<MessageType>,
    #[parent]
    parent: Option<&'a NotificationsUriBuilder<String>>,
}
#[derive(Clone, Debug, UriBuilder)]
pub enum NotifyType {
    Par,
    Pipeline,
    Registration,
    Transfer,
    Smtp,
    #[match_path(path = "smtp/host/{p0}")]
    SmtpHost(String),
    #[match_path(path = "smtp/password/{p0}")]
    SmtpPassword(String),
    #[match_path(path = "smtp/port/{p0}")]
    SmtpPort(String),
    #[match_path(path = "smtp/property/{p0}")]
    #[match_path(path = "smtp/property/{p0}/{p1}")]
    SmtpProperty(String, Option<String>),
    #[match_path(path = "smtp/protocol/{p0}")]
    SmtpProtocol(String),
    #[match_path(path = "smtp/username/{p0}")]
    SmtpUsername(String),
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/notify/{notify_type}")]
pub struct NotifyUriBuilder<'a>
{
    #[param]
    notify_type: Option<NotifyType>,
    #[parent]
    parent: Option<&'a NotificationsUriBuilder<String>>,
}
#[derive(Clone, Debug, UriBuilder)]
pub enum SubscriberOpt {
    Error,
    Issue,
    NewUser,
    Update,
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/subscribers/{subscriber_option}")]
pub struct SubscribersUriBuilder<'a>
{
    #[param]
    subscriber_option: Option<SubscriberOpt>,
    #[parent]
    parent: Option<&'a NotificationsUriBuilder<String>>,
}
impl NotificationsUriBuilder<String>
{
    pub fn allow(&self) -> AllowUriBuilder {
        AllowUriBuilder::from_parent(&Arc::new(self))
    }
    pub fn messages(&self) -> MessagesUriBuilder {
        MessagesUriBuilder::from_parent(&Arc::new(self))
    }
    pub fn notify(&self) -> NotifyUriBuilder {
        NotifyUriBuilder::from_parent(&Arc::new(self))
    }
    pub fn subscribers(&self) -> SubscribersUriBuilder {
        SubscribersUriBuilder::from_parent(&Arc::new(self))
    }
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/xnatTask")]
pub struct XnatTaskUriBuilder<Parent>
where
    Parent: SysUriBuilder,
{
    #[parent]
    parent: Option<Arc<Parent>>,
}
impl XnatTaskUriBuilder<String>
{
    pub fn build_check_node_config_status(&self) -> crate::BuildResult {
        self.build_join("checkNodeConfigurationStatus")
    }
    pub fn build_task_list(&self) -> crate::BuildResult {
        self.build_join("taskList")
    }
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/asyncOps")]
#[match_path(path = "{parent}/asyncOps/{preference}")]
pub struct AsyncOpsUriBuilder<Parent>
where
    Parent: SysUriBuilder,
{
    #[param]
    preference: Option<String>,
    #[parent]
    parent: Option<Arc<Parent>>,
}
#[derive(Clone, Debug, UriBuilder)]
pub enum LogConfigOpt {
    #[match_path(path = "configs")]
    #[match_path(path = "configs/{p0}")]
    Configs(Option<String>),
    #[match_path(path = "download")]
    #[match_path(path = "download/{p0}")]
    Download(Option<String>),
    Elements,
    Reset,
}
#[derive(Clone, Debug, Default, UriBuilder)]
#[match_path(path = "{parent}/logs/{config_opt}")]
pub struct LogsUriBuilder<Parent>
where
    Parent: SysUriBuilder,
{
    #[param]
    config_opt: Option<LogConfigOpt>,
    #[parent]
    parent: Option<Arc<Parent>>,
}
pub trait SystemUri: Version {
    #[inline]
    fn archive(&self) -> ArchiveUriBuilder<String> {
        ArchiveUriBuilder::from_parent(self.root_uri().into())
    }
    #[inline]
    fn async_ops(&self) -> AsyncOpsUriBuilder<String> {
        AsyncOpsUriBuilder::from_parent(self.root_uri().into())
    }
    #[inline]
    fn logs(&self) -> LogsUriBuilder<String> {
        LogsUriBuilder::from_parent(self.root_uri().into())
    }
    #[inline]
    fn notifications(&self) -> NotificationsUriBuilder<String> {
        NotificationsUriBuilder::from_parent(self.root_uri().into())
    }
    #[inline]
    fn xnat_task(&self) -> XnatTaskUriBuilder<String> {
        XnatTaskUriBuilder::from_parent(self.root_uri().into())
    }
}