use rand;
use rand::Rng;
use xml::reader::XmlEvent as ReadEvent;
use xml::writer::XmlEvent as WriteEvent;
use yaserde::MaybeString;
use yaserde::{YaDeserialize as YaDeserializeTrait, YaSerialize as YaSerializeTrait};
use yaserde_derive::{YaDeserialize, YaSerialize};

impl YaDeserializeTrait for HAProxyId {
    fn deserialize<R: std::io::Read>(
        reader: &mut yaserde::de::Deserializer<R>,
    ) -> Result<Self, String> {
        let _field_name = match reader.peek()? {
            ReadEvent::StartElement {
                name, attributes, ..
            } => {
                if attributes.len() > 0 {
                    return Err(String::from(
                        "Attributes not currently supported by HAProxyId",
                    ));
                }

                name.local_name.clone()
            }
            _ => return Err(String::from("Unsupporte ReadEvent type")),
        };
        reader.next_event()?;

        let content = match reader.peek()? {
            ReadEvent::Characters(content) => content.clone(),
            ReadEvent::EndElement { name: _ } => String::new(),
            _ => return Err(String::from("Unsupporte ReadEvent type")),
        };

        Ok(Self(content))
    }
}

impl YaSerializeTrait for HAProxyId {
    fn serialize<W: std::io::Write>(
        &self,
        writer: &mut yaserde::ser::Serializer<W>,
    ) -> Result<(), String> {
        let yaserde_label = writer.get_start_event_name();

        match yaserde_label {
            Some(label) => {
                let struct_start_event = xml::writer::XmlEvent::start_element(label.as_ref());
                writer
                    .write(struct_start_event)
                    .map_err(|_e| format!("Start element {label:?} write failed"))?;
            }
            None => return Err("HAPRoxyId must have a label preset in the writer".to_string()),
        };

        writer
            .write(WriteEvent::characters(&self.0))
            .expect("Writer failed");

        writer
            .write(WriteEvent::end_element())
            .expect("Writer failed");
        Ok(())
    }

    fn serialize_attributes(
        &self,
        _attributes: Vec<xml::attribute::OwnedAttribute>,
        _namespace: xml::namespace::Namespace,
    ) -> Result<
        (
            Vec<xml::attribute::OwnedAttribute>,
            xml::namespace::Namespace,
        ),
        String,
    > {
        todo!()
    }
}

#[derive(PartialEq, Debug)]
pub struct HAProxyId(String);

impl Default for HAProxyId {
    fn default() -> Self {
        let mut rng = rand::thread_rng();
        Self(format!("{:x}.{:x}", rng.gen::<u64>(), rng.gen::<u32>()))
    }
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
#[yaserde(rename = "HAProxy")]
pub struct HAProxy {
    #[yaserde(attribute = true)]
    pub version: String,
    pub general: HaProxyGeneral,
    pub frontends: HAProxyFrontends,
    pub backends: HAProxyBackends,
    pub servers: HAProxyServers,
    pub healthchecks: HAProxyHealthChecks,
    pub acls: MaybeString,
    pub actions: MaybeString,
    pub luas: MaybeString,
    pub fcgis: MaybeString,
    pub errorfiles: MaybeString,
    pub mapfiles: MaybeString,
    pub groups: MaybeString,
    pub users: MaybeString,
    pub cpus: MaybeString,
    pub resolvers: MaybeString,
    pub mailers: MaybeString,
    pub maintenance: Maintenance,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Maintenance {
    #[yaserde(rename = "cronjobs")]
    pub cronjobs: CronJobs,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct CronJobs {
    #[yaserde(rename = "syncCerts")]
    pub sync_certs: u32,
    #[yaserde(rename = "syncCertsCron")]
    pub sync_certs_cron: MaybeString,
    #[yaserde(rename = "updateOcsp")]
    pub update_ocsp: u32,
    #[yaserde(rename = "updateOcspCron")]
    pub update_ocsp_cron: MaybeString,
    #[yaserde(rename = "reloadService")]
    pub reload_service: u32,
    #[yaserde(rename = "reloadServiceCron")]
    pub reload_service_cron: MaybeString,
    #[yaserde(rename = "restartService")]
    pub restart_service: u32,
    #[yaserde(rename = "restartServiceCron")]
    pub restart_service_cron: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HaProxyGeneral {
    pub enabled: i32,
    #[yaserde(rename = "gracefulStop")]
    pub graceful_stop: i32,
    #[yaserde(rename = "hardStopAfter")]
    pub hard_stop_after: String,
    #[yaserde(rename = "closeSpreadTime")]
    pub close_spread_time: MaybeString,
    #[yaserde(rename = "seamlessReload")]
    pub seamless_reload: i32,
    #[yaserde(rename = "storeOcsp")]
    pub store_ocsp: i32,
    #[yaserde(rename = "showIntro")]
    pub show_intro: i32,
    pub peers: Peers,
    pub tuning: Tuning,
    pub defaults: HaProxyDefaults,
    pub logging: HaProxyLogging,
    pub stats: Stats,
    pub cache: HaProxyCache,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Peers {
    pub enabled: i32,
    pub name1: MaybeString,
    pub listen1: MaybeString,
    pub port1: i32,
    pub name2: MaybeString,
    pub listen2: MaybeString,
    pub port2: i32,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Tuning {
    pub root: i32,
    #[yaserde(rename = "maxConnections")]
    pub max_connections: MaybeString,
    pub nbthread: i32,
    #[yaserde(rename = "resolversPrefer")]
    pub resolvers_prefer: String,
    #[yaserde(rename = "sslServerVerify")]
    pub ssl_server_verify: String,
    #[yaserde(rename = "maxDHSize")]
    pub max_dh_size: i32,
    #[yaserde(rename = "bufferSize")]
    pub buffer_size: i32,
    #[yaserde(rename = "spreadChecks")]
    pub spread_checks: i32,
    #[yaserde(rename = "bogusProxyEnabled")]
    pub bogus_proxy_enabled: i32,
    #[yaserde(rename = "luaMaxMem")]
    pub lua_max_mem: i32,
    #[yaserde(rename = "customOptions")]
    pub custom_options: MaybeString,
    #[yaserde(rename = "ocspUpdateEnabled")]
    pub ocs_update_enabled: MaybeString,
    #[yaserde(rename = "ocspUpdateMinDelay")]
    pub ocs_update_min_delay: MaybeString,
    #[yaserde(rename = "ocspUpdateMaxDelay")]
    pub ocs_update_max_delay: MaybeString,
    #[yaserde(rename = "ssl_defaultsEnabled")]
    pub ssl_defaults_enabled: i32,
    #[yaserde(rename = "ssl_bindOptions")]
    pub ssl_bind_options: MaybeString,
    #[yaserde(rename = "ssl_minVersion")]
    pub ssl_min_version: MaybeString,
    #[yaserde(rename = "ssl_maxVersion")]
    pub ssl_max_version: MaybeString,
    #[yaserde(rename = "ssl_cipherList")]
    pub ssl_cipher_list: MaybeString,
    #[yaserde(rename = "ssl_cipherSuites")]
    pub ssl_cipher_suites: MaybeString,
    #[yaserde(rename = "h2_initialWindowSize")]
    pub h2_initial_window_size: Option<MaybeString>,
    #[yaserde(rename = "h2_initialWindowSizeOutgoing")]
    pub h2_initial_window_size_outgoing: Option<MaybeString>,
    #[yaserde(rename = "h2_initialWindowSizeIncoming")]
    pub h2_initial_window_size_incoming: Option<MaybeString>,
    #[yaserde(rename = "h2_maxConcurrentStreams")]
    pub h2_max_concurrent_streams: Option<MaybeString>,
    #[yaserde(rename = "h2_maxConcurrentStreamsOutgoing")]
    pub h2_max_concurrent_streams_outgoing: Option<MaybeString>,
    #[yaserde(rename = "h2_maxConcurrentStreamsIncoming")]
    pub h2_max_concurrent_streams_incoming: Option<MaybeString>,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HaProxyDefaults {
    #[yaserde(rename = "maxConnections")]
    pub max_connections: MaybeString,
    #[yaserde(rename = "maxConnectionsServers")]
    pub max_connections_servers: MaybeString,
    #[yaserde(rename = "timeoutClient")]
    pub timeout_client: String,
    #[yaserde(rename = "timeoutConnect")]
    pub timeout_connect: String,
    #[yaserde(rename = "timeoutCheck")]
    pub timeout_check: MaybeString,
    #[yaserde(rename = "timeoutServer")]
    pub timeout_server: String,
    pub retries: i32,
    pub redispatch: String,
    pub init_addr: String,
    #[yaserde(rename = "customOptions")]
    pub custom_options: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HaProxyLogging {
    pub host: String,
    pub facility: String,
    pub level: String,
    pub length: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Stats {
    pub enabled: i32,
    pub port: i32,
    #[yaserde(rename = "remoteEnabled")]
    pub remote_enabled: i32,
    #[yaserde(rename = "remoteBind")]
    pub remote_bind: MaybeString,
    #[yaserde(rename = "authEnabled")]
    pub auth_enabled: i32,
    #[yaserde(rename = "users")]
    pub users: MaybeString,
    #[yaserde(rename = "allowedUsers")]
    pub allowed_users: MaybeString,
    #[yaserde(rename = "allowedGroups")]
    pub allowed_groups: MaybeString,
    #[yaserde(rename = "customOptions")]
    pub custom_options: MaybeString,
    pub prometheus_enabled: i32,
    pub prometheus_bind: String,
    pub prometheus_path: String,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HaProxyCache {
    pub enabled: i32,
    #[yaserde(rename = "totalMaxSize")]
    pub total_max_size: i32,
    #[yaserde(rename = "maxAge")]
    pub max_age: i32,
    #[yaserde(rename = "maxObjectSize")]
    pub max_object_size: MaybeString,
    #[yaserde(rename = "processVary")]
    pub process_vary: i32,
    #[yaserde(rename = "maxSecondaryEntries")]
    pub max_secondary_entries: i32,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyFrontends {
    pub frontend: Vec<Frontend>,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Frontend {
    #[yaserde(attribute = true)]
    pub uuid: String,
    pub id: HAProxyId,
    pub enabled: i32,
    pub name: String,
    pub description: MaybeString,
    pub bind: String,
    #[yaserde(rename = "bindOptions")]
    pub bind_options: MaybeString,
    pub mode: String,
    #[yaserde(rename = "defaultBackend")]
    pub default_backend: String,
    pub ssl_enabled: i32,
    pub ssl_certificates: MaybeString,
    pub ssl_default_certificate: MaybeString,
    #[yaserde(rename = "ssl_customOptions")]
    pub ssl_custom_options: MaybeString,
    #[yaserde(rename = "ssl_advancedEnabled")]
    pub ssl_advanced_enabled: i32,
    #[yaserde(rename = "ssl_bindOptions")]
    pub ssl_bind_options: MaybeString,
    #[yaserde(rename = "ssl_minVersion")]
    pub ssl_min_version: MaybeString,
    #[yaserde(rename = "ssl_maxVersion")]
    pub ssl_max_version: MaybeString,
    #[yaserde(rename = "ssl_cipherList")]
    pub ssl_cipher_list: MaybeString,
    #[yaserde(rename = "ssl_cipherSuites")]
    pub ssl_cipher_suites: MaybeString,
    #[yaserde(rename = "ssl_hstsEnabled")]
    pub ssl_hsts_enabled: i32,
    #[yaserde(rename = "ssl_hstsIncludeSubDomains")]
    pub ssl_hsts_include_sub_domains: i32,
    #[yaserde(rename = "ssl_hstsPreload")]
    pub ssl_hsts_preload: i32,
    #[yaserde(rename = "ssl_hstsMaxAge")]
    pub ssl_hsts_max_age: i32,
    #[yaserde(rename = "ssl_clientAuthEnabled")]
    pub ssl_client_auth_enabled: i32,
    #[yaserde(rename = "ssl_clientAuthVerify")]
    pub ssl_client_auth_verify: MaybeString,
    #[yaserde(rename = "ssl_clientAuthCAs")]
    pub ssl_client_auth_cas: MaybeString,
    #[yaserde(rename = "ssl_clientAuthCRLs")]
    pub ssl_client_auth_cr_ls: MaybeString,
    #[yaserde(rename = "basicAuthEnabled")]
    pub basic_auth_enabled: i32,
    #[yaserde(rename = "basicAuthUsers")]
    pub basic_auth_users: MaybeString,
    #[yaserde(rename = "basicAuthGroups")]
    pub basic_auth_groups: MaybeString,
    #[yaserde(rename = "tuning_maxConnections")]
    pub tuning_max_connections: MaybeString,
    #[yaserde(rename = "tuning_timeoutClient")]
    pub tuning_timeout_client: MaybeString,
    #[yaserde(rename = "tuning_timeoutHttpReq")]
    pub tuning_timeout_http_req: MaybeString,
    #[yaserde(rename = "tuning_timeoutHttpKeepAlive")]
    pub tuning_timeout_http_keep_alive: MaybeString,
    #[yaserde(rename = "linkedCpuAffinityRules")]
    pub linked_cpu_affinity_rules: MaybeString,
    pub tuning_shards: MaybeString,
    #[yaserde(rename = "logging_dontLogNull")]
    pub logging_dont_log_null: i32,
    #[yaserde(rename = "logging_dontLogNormal")]
    pub logging_dont_log_normal: i32,
    #[yaserde(rename = "logging_logSeparateErrors")]
    pub logging_log_separate_errors: i32,
    #[yaserde(rename = "logging_detailedLog")]
    pub logging_detailed_log: i32,
    #[yaserde(rename = "logging_socketStats")]
    pub logging_socket_stats: i32,
    pub stickiness_pattern: MaybeString,
    #[yaserde(rename = "stickiness_dataTypes")]
    pub stickiness_data_types: MaybeString,
    pub stickiness_expire: MaybeString,
    pub stickiness_size: MaybeString,
    pub stickiness_counter: i32,
    pub stickiness_counter_key: MaybeString,
    pub stickiness_length: MaybeString,
    #[yaserde(rename = "stickiness_connRatePeriod")]
    pub stickiness_conn_rate_period: MaybeString,
    #[yaserde(rename = "stickiness_sessRatePeriod")]
    pub stickiness_sess_rate_period: MaybeString,
    #[yaserde(rename = "stickiness_httpReqRatePeriod")]
    pub stickiness_http_req_rate_period: MaybeString,
    #[yaserde(rename = "stickiness_httpErrRatePeriod")]
    pub stickiness_http_err_rate_period: MaybeString,
    #[yaserde(rename = "stickiness_bytesInRatePeriod")]
    pub stickiness_bytes_in_rate_period: MaybeString,
    #[yaserde(rename = "stickiness_bytesOutRatePeriod")]
    pub stickiness_bytes_out_rate_period: MaybeString,
    #[yaserde(rename = "http2Enabled")]
    pub http2_enabled: i32,
    #[yaserde(rename = "http2Enabled_nontls")]
    pub http2_enabled_nontls: i32,
    pub advertised_protocols: MaybeString,
    #[yaserde(rename = "forwardFor")]
    pub forward_for: i32,
    pub prometheus_enabled: i32,
    pub prometheus_path: MaybeString,
    #[yaserde(rename = "connectionBehaviour")]
    pub connection_behaviour: MaybeString,
    #[yaserde(rename = "customOptions")]
    pub custom_options: MaybeString,
    #[yaserde(rename = "linkedActions")]
    pub linked_actions: MaybeString,
    #[yaserde(rename = "linkedErrorfiles")]
    pub linked_error_files: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyBackends {
    #[yaserde(rename = "backend")]
    pub backends: Vec<HAProxyBackend>,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyBackend {
    #[yaserde(attribute = true, rename = "uuid")]
    pub uuid: String,
    #[yaserde(rename = "id")]
    pub id: HAProxyId,
    #[yaserde(rename = "enabled")]
    pub enabled: u8,
    #[yaserde(rename = "name")]
    pub name: String,
    #[yaserde(rename = "description")]
    pub description: MaybeString,
    #[yaserde(rename = "mode")]
    pub mode: String,
    #[yaserde(rename = "algorithm")]
    pub algorithm: String,
    #[yaserde(rename = "random_draws")]
    pub random_draws: Option<u32>,
    #[yaserde(rename = "proxyProtocol")]
    pub proxy_protocol: MaybeString,
    #[yaserde(rename = "linkedServers")]
    pub linked_servers: MaybeString,
    #[yaserde(rename = "linkedFcgi")]
    pub linked_fcgi: MaybeString,
    #[yaserde(rename = "linkedResolver")]
    pub linked_resolver: MaybeString,
    #[yaserde(rename = "resolverOpts")]
    pub resolver_opts: MaybeString,
    #[yaserde(rename = "resolvePrefer")]
    pub resolve_prefer: MaybeString,
    #[yaserde(rename = "source")]
    pub source: MaybeString,
    #[yaserde(rename = "healthCheckEnabled")]
    pub health_check_enabled: u8,
    #[yaserde(rename = "healthCheck")]
    pub health_check: MaybeString,
    #[yaserde(rename = "healthCheckLogStatus")]
    pub health_check_log_status: u8,
    #[yaserde(rename = "checkInterval")]
    pub check_interval: MaybeString,
    #[yaserde(rename = "checkDownInterval")]
    pub check_down_interval: MaybeString,
    #[yaserde(rename = "healthCheckFall")]
    pub health_check_fall: MaybeString,
    #[yaserde(rename = "healthCheckRise")]
    pub health_check_rise: MaybeString,
    #[yaserde(rename = "linkedMailer")]
    pub linked_mailer: MaybeString,
    #[yaserde(rename = "http2Enabled")]
    pub http2_enabled: u8,
    #[yaserde(rename = "http2Enabled_nontls")]
    pub http2_enabled_nontls: u8,
    #[yaserde(rename = "ba_advertised_protocols")]
    pub ba_advertised_protocols: MaybeString,
    #[yaserde(rename = "forwardFor")]
    pub forward_for: Option<i32>,
    #[yaserde(rename = "forwardedHeader")]
    pub forwarded_header: Option<MaybeString>,
    #[yaserde(rename = "forwardedHeaderParameters")]
    pub forwarded_header_parameters: Option<MaybeString>,
    pub persistence: MaybeString,
    pub persistence_cookiemode: MaybeString,
    pub persistence_cookiename: MaybeString,
    pub persistence_stripquotes: u8,
    pub stickiness_pattern: MaybeString,
    #[yaserde(rename = "stickiness_dataTypes")]
    pub stickiness_data_types: MaybeString,
    pub stickiness_expire: String,
    pub stickiness_size: String,
    pub stickiness_cookiename: MaybeString,
    pub stickiness_cookielength: MaybeString,
    #[yaserde(rename = "stickiness_connRatePeriod")]
    pub stickiness_conn_rate_period: String,
    #[yaserde(rename = "stickiness_sessRatePeriod")]
    pub stickiness_sess_rate_period: String,
    #[yaserde(rename = "stickiness_httpReqRatePeriod")]
    pub stickiness_http_req_rate_period: String,
    #[yaserde(rename = "stickiness_httpErrRatePeriod")]
    pub stickiness_http_err_rate_period: String,
    #[yaserde(rename = "stickiness_bytesInRatePeriod")]
    pub stickiness_bytes_in_rate_period: String,
    #[yaserde(rename = "stickiness_bytesOutRatePeriod")]
    pub stickiness_bytes_out_rate_period: String,
    #[yaserde(rename = "basicAuthEnabled")]
    pub basic_auth_enabled: u8,
    #[yaserde(rename = "basicAuthUsers")]
    pub basic_auth_users: MaybeString,
    #[yaserde(rename = "basicAuthGroups")]
    pub basic_auth_groups: MaybeString,
    #[yaserde(rename = "tuning_timeoutConnect")]
    pub tuning_timeout_connect: MaybeString,
    #[yaserde(rename = "tuning_timeoutCheck")]
    pub tuning_timeout_check: MaybeString,
    #[yaserde(rename = "tuning_timeoutServer")]
    pub tuning_timeout_server: MaybeString,
    #[yaserde(rename = "tuning_retries")]
    pub tuning_retries: MaybeString,
    #[yaserde(rename = "customOptions")]
    pub custom_options: MaybeString,
    #[yaserde(rename = "tuning_defaultserver")]
    pub tuning_defaultserver: MaybeString,
    #[yaserde(rename = "tuning_noport")]
    pub tuning_noport: u8,
    #[yaserde(rename = "tuning_httpreuse")]
    pub tuning_httpreuse: MaybeString,
    #[yaserde(rename = "tuning_caching")]
    pub tuning_caching: u8,
    #[yaserde(rename = "linkedActions")]
    pub linked_actions: MaybeString,
    #[yaserde(rename = "linkedErrorfiles")]
    pub linked_errorfiles: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyServers {
    #[yaserde(rename = "server")]
    pub servers: Vec<HAProxyServer>,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyServer {
    #[yaserde(attribute = true, rename = "uuid")]
    pub uuid: String,
    pub id: HAProxyId,
    pub enabled: u8,
    pub name: String,
    pub description: MaybeString,
    pub address: String,
    pub port: u16,
    pub checkport: MaybeString,
    pub mode: String,
    pub multiplexer_protocol: MaybeString,
    #[yaserde(rename = "type")]
    pub server_type: String,
    #[yaserde(rename = "serviceName")]
    pub service_name: MaybeString,
    pub number: MaybeString,
    #[yaserde(rename = "linkedResolver")]
    pub linked_resolver: MaybeString,
    #[yaserde(rename = "resolverOpts")]
    pub resolver_opts: MaybeString,
    #[yaserde(rename = "resolvePrefer")]
    pub resolve_prefer: MaybeString,
    pub ssl: u8,
    #[yaserde(rename = "sslSNI")]
    pub ssl_sni: MaybeString,
    #[yaserde(rename = "sslVerify")]
    pub ssl_verify: u8,
    #[yaserde(rename = "sslCA")]
    pub ssl_ca: MaybeString,
    #[yaserde(rename = "sslCRL")]
    pub ssl_crl: MaybeString,
    #[yaserde(rename = "sslClientCertificate")]
    pub ssl_client_certificate: MaybeString,
    #[yaserde(rename = "maxConnections")]
    pub max_connections: MaybeString,
    pub weight: Option<u32>,
    #[yaserde(rename = "checkInterval")]
    pub check_interval: MaybeString,
    #[yaserde(rename = "checkDownInterval")]
    pub check_down_interval: MaybeString,
    pub source: MaybeString,
    pub advanced: MaybeString,
    #[yaserde(rename = "unix_socket")]
    pub unix_socket: MaybeString,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyHealthChecks {
    #[yaserde(rename = "healthcheck")]
    pub healthchecks: Vec<HAProxyHealthCheck>,
}

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct HAProxyHealthCheck {
    #[yaserde(attribute = true)]
    pub uuid: String,
    pub name: String,
    pub description: MaybeString,
    #[yaserde(rename = "type")]
    pub health_check_type: String,
    pub interval: String,
    pub ssl: MaybeString,
    #[yaserde(rename = "sslSNI")]
    pub ssl_sni: MaybeString,
    pub force_ssl: u8,
    pub checkport: MaybeString,
    pub http_method: MaybeString,
    pub http_uri: MaybeString,
    pub http_version: MaybeString,
    #[yaserde(rename = "http_host")]
    pub http_host: MaybeString,
    #[yaserde(rename = "http_expressionEnabled")]
    pub http_expression_enabled: Option<u8>,
    pub http_expression: MaybeString,
    pub http_negate: MaybeString,
    pub http_value: MaybeString,
    pub tcp_enabled: MaybeString,
    #[yaserde(rename = "tcp_sendValue")]
    pub tcp_send_value: MaybeString,
    #[yaserde(rename = "tcp_matchType")]
    pub tcp_match_type: MaybeString,
    pub tcp_negate: MaybeString,
    #[yaserde(rename = "tcp_matchValue")]
    pub tcp_match_value: MaybeString,
    pub agent_port: MaybeString,
    pub mysql_user: MaybeString,
    pub mysql_post41: MaybeString,
    pub pgsql_user: MaybeString,
    pub smtp_domain: MaybeString,
    pub esmtp_domain: MaybeString,
    #[yaserde(rename = "agentPort")]
    pub agent_port_uppercase: MaybeString,
    #[yaserde(rename = "dbUser")]
    pub db_user: MaybeString,
    #[yaserde(rename = "smtpDomain")]
    pub smtp_domain_uppercase: MaybeString,
}
