// file: kb_lib/src/detect/types.rs

//! Detection pipeline input and output types.

/// One normalized observation ready to be persisted.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionObservationInput {
    /// Observation kind.
    pub observation_kind: std::string::String,
    /// Observation source family.
    pub source_kind: crate::ObservationSourceKind,
    /// Optional logical source endpoint name.
    pub endpoint_name: std::option::Option<std::string::String>,
    /// Logical object key, for example a mint, signature or pool address.
    pub object_key: std::string::String,
    /// Optional slot number.
    pub slot: std::option::Option<u64>,
    /// JSON payload.
    pub payload: serde_json::Value,
}

impl DetectionObservationInput {
    /// Creates a new detection observation input.
    pub fn new(
        observation_kind: std::string::String,
        source_kind: crate::ObservationSourceKind,
        endpoint_name: std::option::Option<std::string::String>,
        object_key: std::string::String,
        slot: std::option::Option<u64>,
        payload: serde_json::Value,
    ) -> Self {
        return Self {
            observation_kind,
            source_kind,
            endpoint_name,
            object_key,
            slot,
            payload,
        };
    }
}

/// One normalized signal ready to be persisted.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionSignalInput {
    /// Signal kind.
    pub signal_kind: std::string::String,
    /// Signal severity.
    pub severity: crate::AnalysisSignalSeverity,
    /// Logical object key, for example a mint, signature or pool address.
    pub object_key: std::string::String,
    /// Optional related observation id.
    pub related_observation_id: std::option::Option<i64>,
    /// Optional score.
    pub score: std::option::Option<f64>,
    /// JSON payload.
    pub payload: serde_json::Value,
}

impl DetectionSignalInput {
    /// Creates a new detection signal input.
    pub fn new(
        signal_kind: std::string::String,
        severity: crate::AnalysisSignalSeverity,
        object_key: std::string::String,
        related_observation_id: std::option::Option<i64>,
        score: std::option::Option<f64>,
        payload: serde_json::Value,
    ) -> Self {
        return Self {
            signal_kind,
            severity,
            object_key,
            related_observation_id,
            score,
            payload,
        };
    }
}

/// One token candidate detected from a technical source.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionTokenCandidateInput {
    /// Token mint address.
    pub mint: std::string::String,
    /// Optional token symbol.
    pub symbol: std::option::Option<std::string::String>,
    /// Optional token name.
    pub name: std::option::Option<std::string::String>,
    /// Optional decimals.
    pub decimals: std::option::Option<u8>,
    /// Token program id.
    pub token_program: std::string::String,
    /// Whether the token is typically used as quote token.
    pub is_quote_token: bool,
    /// Observation source family.
    pub source_kind: crate::ObservationSourceKind,
    /// Optional source endpoint logical name.
    pub endpoint_name: std::option::Option<std::string::String>,
    /// Optional slot number.
    pub slot: std::option::Option<u64>,
    /// Observation kind.
    pub observation_kind: std::string::String,
    /// Observation payload.
    pub observation_payload: serde_json::Value,
    /// Signal kind.
    pub signal_kind: std::string::String,
    /// Signal severity.
    pub signal_severity: crate::AnalysisSignalSeverity,
    /// Optional signal score.
    pub signal_score: std::option::Option<f64>,
    /// Optional dedicated signal payload.
    pub signal_payload: std::option::Option<serde_json::Value>,
}

impl DetectionTokenCandidateInput {
    /// Creates a new token candidate input.
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        mint: std::string::String,
        symbol: std::option::Option<std::string::String>,
        name: std::option::Option<std::string::String>,
        decimals: std::option::Option<u8>,
        token_program: std::string::String,
        is_quote_token: bool,
        source_kind: crate::ObservationSourceKind,
        endpoint_name: std::option::Option<std::string::String>,
        slot: std::option::Option<u64>,
        observation_kind: std::string::String,
        observation_payload: serde_json::Value,
        signal_kind: std::string::String,
        signal_severity: crate::AnalysisSignalSeverity,
        signal_score: std::option::Option<f64>,
        signal_payload: std::option::Option<serde_json::Value>,
    ) -> Self {
        return Self {
            mint,
            symbol,
            name,
            decimals,
            token_program,
            is_quote_token,
            source_kind,
            endpoint_name,
            slot,
            observation_kind,
            observation_payload,
            signal_kind,
            signal_severity,
            signal_score,
            signal_payload,
        };
    }
}

/// Result of one token candidate persistence operation.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionTokenCandidateResult {
    /// Persisted token id.
    pub token_id: i64,
    /// Persisted observation id.
    pub observation_id: i64,
    /// Persisted signal id.
    pub signal_id: i64,
}

/// One pool candidate detected from a technical source.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionPoolCandidateInput {
    /// Pool address.
    pub pool_address: std::string::String,
    /// DEX program id or router program id that matched.
    pub dex_program_id: std::string::String,
    /// Observation source family.
    pub source_kind: crate::ObservationSourceKind,
    /// Optional source endpoint logical name.
    pub endpoint_name: std::option::Option<std::string::String>,
    /// Optional slot number.
    pub slot: std::option::Option<u64>,
    /// Observation kind.
    pub observation_kind: std::string::String,
    /// Observation payload.
    pub observation_payload: serde_json::Value,
    /// Signal kind.
    pub signal_kind: std::string::String,
    /// Signal severity.
    pub signal_severity: crate::AnalysisSignalSeverity,
    /// Optional signal score.
    pub signal_score: std::option::Option<f64>,
    /// Optional dedicated signal payload.
    pub signal_payload: std::option::Option<serde_json::Value>,
}

impl DetectionPoolCandidateInput {
    /// Creates a new pool candidate input.
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        pool_address: std::string::String,
        dex_program_id: std::string::String,
        source_kind: crate::ObservationSourceKind,
        endpoint_name: std::option::Option<std::string::String>,
        slot: std::option::Option<u64>,
        observation_kind: std::string::String,
        observation_payload: serde_json::Value,
        signal_kind: std::string::String,
        signal_severity: crate::AnalysisSignalSeverity,
        signal_score: std::option::Option<f64>,
        signal_payload: std::option::Option<serde_json::Value>,
    ) -> Self {
        return Self {
            pool_address,
            dex_program_id,
            source_kind,
            endpoint_name,
            slot,
            observation_kind,
            observation_payload,
            signal_kind,
            signal_severity,
            signal_score,
            signal_payload,
        };
    }
}

/// Result of one pool candidate persistence operation.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DetectionPoolCandidateResult {
    /// Persisted dex id.
    pub dex_id: i64,
    /// Persisted pool id.
    pub pool_id: i64,
    /// Persisted pool listing id.
    pub pool_listing_id: i64,
    /// Persisted observation id.
    pub observation_id: i64,
    /// Persisted signal id.
    pub signal_id: i64,
}
