use std::collections::HashMap;

use harmony::{
    data::Id,
    inventory::Inventory,
    maestro::Maestro,
    modules::{
        monitoring::{
            alert_channel::discord_alert_channel::DiscordWebhook,
            alert_rule::prometheus_alert_rule::AlertManagerRuleGroup,
            kube_prometheus::{
                helm_prometheus_alert_score::HelmPrometheusAlertingScore,
                types::{
                    HTTPScheme, MatchExpression, Operator, Selector, ServiceMonitor,
                    ServiceMonitorEndpoint,
                },
            },
        },
        prometheus::alerts::k8s::pvc::high_pvc_fill_rate_over_two_days,
        tenant::TenantScore,
    },
    topology::{
        K8sAnywhereTopology, Url,
        tenant::{ResourceLimits, TenantConfig, TenantNetworkPolicy},
    },
};

#[tokio::main]
async fn main() {
    let tenant = TenantScore {
        config: TenantConfig {
            id: Id::from_string("1234".to_string()),
            name: "test-tenant".to_string(),
            resource_limits: ResourceLimits {
                cpu_request_cores: 6.0,
                cpu_limit_cores: 4.0,
                memory_request_gb: 4.0,
                memory_limit_gb: 4.0,
                storage_total_gb: 10.0,
            },
            network_policy: TenantNetworkPolicy::default(),
        },
    };

    let discord_receiver = DiscordWebhook {
        name: "test-discord".to_string(),
        url: Url::Url(url::Url::parse("https://discord.doesnt.exist.com").unwrap()),
    };

    let high_pvc_fill_rate_over_two_days_alert = high_pvc_fill_rate_over_two_days();

    let additional_rules =
        AlertManagerRuleGroup::new("pvc-alerts", vec![high_pvc_fill_rate_over_two_days_alert]);

    let service_monitor_endpoint = ServiceMonitorEndpoint {
        port: Some("80".to_string()),
        path: Some("/metrics".to_string()),
        scheme: Some(HTTPScheme::HTTP),
        ..Default::default()
    };

    let service_monitor = ServiceMonitor {
        name: "test-service-monitor".to_string(),
        selector: Selector {
            match_labels: HashMap::new(),
            match_expressions: vec![MatchExpression {
                key: "test".to_string(),
                operator: Operator::In,
                values: vec!["test-service".to_string()],
            }],
        },
        endpoints: vec![service_monitor_endpoint],
        ..Default::default()
    };

    let alerting_score = HelmPrometheusAlertingScore {
        receivers: vec![Box::new(discord_receiver)],
        rules: vec![Box::new(additional_rules)],
        service_monitors: vec![service_monitor],
    };
    let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
        Inventory::autoload(),
        K8sAnywhereTopology::from_env(),
    )
    .await
    .unwrap();

    maestro.register_all(vec![Box::new(tenant), Box::new(alerting_score)]);
    harmony_cli::init(maestro, None).await.unwrap();
}
