use async_trait::async_trait;
use dyn_clone::DynClone;
use serde::Serialize;
use std::fmt::Debug;
use std::sync::Arc;

use crate::executors::ExecutorError;
use crate::interpret::InterpretError;

use crate::inventory::Inventory;
use crate::{interpret::Outcome, topology::Topology};

/// Represents an entity responsible for collecting and organizing observability data
/// from various telemetry sources such as Prometheus or Datadog
/// A `Monitor` abstracts the logic required to scrape, aggregate, and structure
/// monitoring data, enabling consistent processing regardless of the underlying data source.
#[async_trait]
pub trait Monitor {
    async fn provision_monitor(
        &self,
        alert_receivers: Option<Vec<Box<dyn AlertChannelConfig>>>,
    ) -> Result<Outcome, InterpretError>;

    fn delete_monitor(&self) -> Result<Outcome, InterpretError>;
}

#[async_trait]
pub trait AlertChannel: Debug + Send + Sync {
    async fn register_alert_channel(&self) -> Result<Outcome, ExecutorError>;
    //async fn get_channel_id(&self) -> String;
}

#[async_trait]
pub trait AlertChannelConfig: Debug + Send + Sync + DynClone {
    async fn build_alert_channel(&self) -> Result<Box<dyn AlertChannel>, InterpretError>;
}

dyn_clone::clone_trait_object!(AlertChannelConfig);
