use crate::error::{PluginManagerError, PluginManagerResult};
use crate::status::PluginStatus;
use crate::manager::types::{PluginInstance, PluginMap};
use crate::manager::unloader::{check_plugin_dependencies, cleanup_single_temp_files};
use std::collections::HashMap;
use tracing::{debug, error, info, trace, warn};
pub async fn remove_child_from_parent(
plugins: PluginMap,
child_id: &str,
parent_id: &str,
) -> bool {
trace!("准备从父插件移除子插件 - 父插件: {}, 子插件: {}", parent_id, child_id);
let mut plugins = plugins.write().await;
if let Some(parent) = plugins.get_mut(parent_id) {
let original_len = parent.child_plugins.len();
debug!("父插件 {} 当前有 {} 个子插件", parent_id, original_len);
parent.child_plugins.retain(|child| child.id != child_id);
let removed = parent.child_plugins.len() < original_len;
if removed {
info!(
"已从父插件 {} 的子插件列表中移除子插件 {}",
parent_id, child_id
);
debug!("父插件 {} 现在有 {} 个子插件", parent_id, parent.child_plugins.len());
} else {
trace!("子插件 {} 不在父插件 {} 的子插件列表中", child_id, parent_id);
}
removed
} else {
warn!("父插件 {} 不存在,无法移除子插件 {}", parent_id, child_id);
false
}
}
pub fn get_unload_info(
plugins: &HashMap<String, PluginInstance>,
plugin_id: &str,
) -> PluginManagerResult<(Vec<String>, bool, Option<String>)> {
trace!("获取插件卸载信息: {}", plugin_id);
let plugin_instance = plugins.get(plugin_id)
.ok_or_else(|| {
error!("插件不存在: {}", plugin_id);
PluginManagerError::not_found(plugin_id)
})?;
debug!("找到插件实例: {} (状态: {:?})",
plugin_instance.metadata.name, plugin_instance.status);
debug!("检查插件依赖关系");
check_plugin_dependencies(plugins, plugin_id)?;
trace!("依赖关系检查通过");
let child_plugin_ids: Vec<String> = plugin_instance
.child_plugins
.iter()
.filter_map(|child| {
if plugins.contains_key(&child.id) {
trace!("找到有效的子插件: {}", child.id);
Some(child.id.clone())
} else {
warn!(
"子插件 {} 在父插件 {} 的列表中,但实际不存在,将跳过",
child.id, plugin_id
);
None
}
})
.collect();
debug!("插件 {} 有 {} 个子插件", plugin_id, child_plugin_ids.len());
let is_sub_plugin = plugin_instance.metadata.is_sub_plugin;
let parent_id = plugin_instance.metadata.parent_plugin_id.clone();
if is_sub_plugin {
debug!("这是子插件,父插件ID: {:?}", parent_id);
} else {
debug!("这是主插件");
}
Ok((child_plugin_ids, is_sub_plugin, parent_id))
}
pub async fn perform_unload(
plugins: PluginMap,
plugin_id: &str,
) -> PluginManagerResult<PluginInstance> {
trace!("开始执行插件卸载: {}", plugin_id);
let mut plugins = plugins.write().await;
let plugin_instance = plugins.remove(plugin_id)
.ok_or_else(|| {
error!("插件在卸载过程中被移除: {}", plugin_id);
PluginManagerError::not_found(format!("插件在卸载过程中被移除: {}", plugin_id))
})?;
debug!("插件实例已从映射表中移除: {} ({})",
plugin_instance.metadata.name, plugin_id);
drop(plugins);
trace!("开始清理插件临时文件");
cleanup_single_temp_files(&plugin_instance).await;
debug!("临时文件清理完成");
info!(
plugin_id = %plugin_id,
plugin_name = %plugin_instance.metadata.name,
plugin_version = %plugin_instance.metadata.version,
fingerprint = %plugin_instance.fingerprint,
"插件卸载成功: {} ({}) v{}",
plugin_instance.metadata.name,
plugin_id,
plugin_instance.metadata.version
);
trace!("插件卸载流程完成");
Ok(plugin_instance)
}
pub fn get_unload_order(
plugins: &HashMap<String, PluginInstance>,
) -> Vec<String> {
trace!("计算插件卸载顺序");
let mut child_ids = Vec::new();
let mut parent_ids = Vec::new();
for (id, instance) in plugins.iter() {
if instance.metadata.is_sub_plugin {
trace!("发现子插件: {}", id);
child_ids.push(id.clone());
} else {
trace!("发现主插件: {}", id);
parent_ids.push(id.clone());
}
}
debug!("卸载顺序: {} 个子插件, {} 个主插件", child_ids.len(), parent_ids.len());
let order = child_ids.into_iter()
.chain(parent_ids.into_iter())
.collect();
trace!("卸载顺序计算完成: {:?}", order);
order
}