//! Phase 4: factory that builds a stub `LangfuseStream`. Task 22 upgrades
//! it to read credentials from params and construct a real client.

use std::sync::Arc;

use async_trait::async_trait;

use dirigent_core::sharing::{StreamBuildError, StreamConfig, StreamFactory};
use dirigent_protocol::streaming::SessionStream;

use crate::client::{LangfuseConfig, LangfuseStream};

pub struct LangfuseFactory;

#[async_trait]
impl StreamFactory for LangfuseFactory {
    fn kind(&self) -> &'static str { "langfuse" }

    async fn build(&self, cfg: &StreamConfig) -> Result<Arc<dyn SessionStream>, StreamBuildError> {
        // Parse params. Required fields:
        //   host:       String (URL)
        //   public_key: String
        //   secret_key: String
        //
        // Phase 4 stub: parse-or-fail, then construct LangfuseStream with
        // the parsed config. Task 22 uses the host to build a reqwest client.

        let host = cfg.params
            .get("host").and_then(|v| v.as_str())
            .ok_or_else(|| StreamBuildError::Config("missing `host` (url string)".into()))?;
        let public_key = cfg.params
            .get("public_key").and_then(|v| v.as_str())
            .ok_or_else(|| StreamBuildError::Config("missing `public_key`".into()))?;
        let secret_key = cfg.params
            .get("secret_key").and_then(|v| v.as_str())
            .ok_or_else(|| StreamBuildError::Config("missing `secret_key`".into()))?;

        let lf_cfg = LangfuseConfig {
            host: host.to_string(),
            public_key: public_key.to_string(),
            secret_key: secret_key.to_string(),
        };

        let stream = LangfuseStream::new(cfg.name.clone(), lf_cfg, cfg.scope.clone())
            .map_err(|e| StreamBuildError::Transport(e.to_string()))?;
        Ok(stream as Arc<dyn SessionStream>)
    }
}
