//! Sample plugin integration test.

#![expect(clippy::tests_outside_test_module, reason = "integration test module")]

use std::path::PathBuf;
use std::sync::{Arc, Mutex};

use pixelflow_core::{Core, CoreConfig, LogRecord, LogSink, Logger};

#[derive(Default)]
struct RecordingSink {
    records: Mutex<Vec<LogRecord>>,
}

impl LogSink for RecordingSink {
    fn log(&self, record: &LogRecord) {
        self.records
            .lock()
            .expect("record lock poisoned")
            .push(record.clone());
    }
}

#[test]
#[ignore = "requires PIXELFLOW_SAMPLE_PLUGIN_PATH from a built sample plugin"]
fn sample_rust_plugin_loads_and_registers_filter() {
    let path = std::env::var_os("PIXELFLOW_SAMPLE_PLUGIN_PATH")
        .map(PathBuf::from)
        .expect("PIXELFLOW_SAMPLE_PLUGIN_PATH must point to sample plugin dynamic library")
        .canonicalize()
        .expect("sample plugin path should be absolute or canonicalizable");
    let directory = path
        .parent()
        .expect("sample plugin path should have parent")
        .to_path_buf();

    let sink = Arc::new(RecordingSink::default());
    let logger = Logger::new(sink.clone());
    let mut config = CoreConfig::default()
        .with_auto_load_plugins(false)
        .with_logger(logger);
    config.plugin_directories_mut().push(directory);

    let core = Core::with_config(config).expect("core should load sample plugin");

    let loaded_plugin_names = core
        .loaded_plugins()
        .iter()
        .map(|plugin| plugin.name().to_owned())
        .collect::<Vec<_>>();
    let log_messages = sink
        .records
        .lock()
        .expect("record lock poisoned")
        .iter()
        .map(|record| record.message().to_owned())
        .collect::<Vec<_>>();

    assert!(
        core.registry().contains_filter("sample.identity"),
        "loaded_plugins={loaded_plugin_names:?}; logs={log_messages:?}"
    );
    assert!(
        core.registry()
            .metadata_schema()
            .contains_key("pixelflow/sample:enabled")
    );
    assert!(
        core.loaded_plugins()
            .iter()
            .any(|plugin| plugin.name() == "pixelflow-sample-plugin")
    );
}
