use itertools::Itertools;
use perspective_client::config::ViewConfig;
use perspective_js::utils::{ApiResult, JsValueSerdeExt};
use serde::Serialize;
use crate::config::ColumnConfigSchema;
use crate::renderer::Renderer;
use crate::session::SessionMetadata;
#[derive(Default, Serialize)]
struct ColumnStats {
#[serde(skip_serializing_if = "Option::is_none")]
abs_max: Option<f64>,
}
pub fn get_plugin_config_schema(
renderer: &Renderer,
view_config: &ViewConfig,
) -> ApiResult<ColumnConfigSchema> {
let plugin = renderer.get_active_plugin()?;
let view_config_js =
wasm_bindgen::JsValue::from_serde_ext(view_config).unwrap_or(wasm_bindgen::JsValue::NULL);
let raw = plugin._plugin_config_schema(&view_config_js)?;
serde_wasm_bindgen::from_value(raw).map_err(|e| e.into())
}
pub fn get_column_config_schema(
renderer: &Renderer,
view_config: &ViewConfig,
metadata: &SessionMetadata,
column_name: &str,
current_value: Option<&serde_json::Map<String, serde_json::Value>>,
abs_max: Option<f64>,
) -> ApiResult<ColumnConfigSchema> {
let plugin = renderer.get_active_plugin()?;
let plugin_config = renderer.metadata();
let names = &plugin_config.config_column_names;
let group = view_config
.columns
.iter()
.find_position(|maybe_s| maybe_s.as_deref() == Some(column_name))
.and_then(|(idx, _)| names.get(idx))
.map(|s| s.as_str());
let view_type = if let Some(x) = metadata.get_column_view_type(column_name) {
x
} else {
return Ok(ColumnConfigSchema { fields: vec![] });
};
let current_js = wasm_bindgen::JsValue::from_serde_ext(¤t_value)
.unwrap_or(wasm_bindgen::JsValue::NULL);
let view_config_js =
wasm_bindgen::JsValue::from_serde_ext(view_config).unwrap_or(wasm_bindgen::JsValue::NULL);
let stats = ColumnStats { abs_max };
let stats_js =
wasm_bindgen::JsValue::from_serde_ext(&stats).unwrap_or(wasm_bindgen::JsValue::NULL);
let raw = plugin._column_config_schema(
&view_type.to_string(),
group,
column_name,
¤t_js,
&view_config_js,
&stats_js,
)?;
serde_wasm_bindgen::from_value(raw).map_err(|e| e.into())
}