package cd.casic.plugin.utils;

import cd.casic.plugin.OpsPluginDescriptor;
import cd.casic.plugin.dataobject.dto.PluginSpecStorage;
import cn.hutool.core.util.StrUtil;
import org.pf4j.DefaultPluginDescriptor;
import org.pf4j.PluginDependency;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 重构插件的信息
 * @author: mianbin
 * @date: 2025/5/19 17:07
 * @version: 1.0
 */
public class PluginDescriptorUtils {
    public static final String PLUGIN_ID = "plugin.id";
    public static final String PLUGIN_DESCRIPTION = "plugin.description";
    public static final String PLUGIN_CLASS = "plugin.class";
    public static final String PLUGIN_VERSION = "plugin.version";
    public static final String PLUGIN_PROVIDER = "plugin.provider";
    public static final String PLUGIN_DEPENDENCIES = "plugin.dependencies";
    public static final String PLUGIN_REQUIRES = "plugin.requires";
    public static final String PLUGIN_LICENSE = "plugin.license";
    public static final String MYBATIS_MAPPER_LOCATION = "mybatis.mapper.location";
    public static final String STATIC_LOCATIONS = "static.locations";
    public static final String CONFIG_FILE_NAME = "plugin.config.file";
    public static final String CONFIG_FILE_ACTIVE = "plugin.config.active";

    public static PluginSpecStorage propertiesToStorage(Properties properties) {
        PluginSpecStorage pluginDescriptor = new PluginSpecStorage();
        // 设置插件 ID
        pluginDescriptor.setPluginId(properties.getProperty(PLUGIN_ID));
        // 设置插件描述
        pluginDescriptor.setPluginDescription(StrUtil.emptyToDefault(properties.getProperty(PLUGIN_DESCRIPTION), ""));
        // 设置插件类
        setIfNotEmpty(pluginDescriptor::setPluginClass, properties.getProperty(PLUGIN_CLASS));
        // 设置插件版本
        setIfNotEmpty(pluginDescriptor::setVersion, properties.getProperty(PLUGIN_VERSION));
        // 设置插件提供者
        pluginDescriptor.setProvider(properties.getProperty(PLUGIN_PROVIDER));
        // 设置插件依赖要求
        pluginDescriptor.setRequires(StrUtil.emptyToDefault(properties.getProperty(PLUGIN_REQUIRES), "0.0.0"));
        // 设置 MyBatis Mapper 位置
        pluginDescriptor.setMapperXmlDir(properties.getProperty(MYBATIS_MAPPER_LOCATION));
        // 设置静态资源位置
        pluginDescriptor.setStaticDir(properties.getProperty(STATIC_LOCATIONS));
        // 设置插件许可证
        pluginDescriptor.setLicense(properties.getProperty(PLUGIN_LICENSE));
        // 设置插件依赖列表
        String dependencies = properties.getProperty(PLUGIN_DEPENDENCIES);
        pluginDescriptor.setDependencies(StrUtil.isEmpty(dependencies) ?
                Collections.emptyList() :
                Arrays.stream(dependencies.trim().split(","))
                        .map(dependency -> new PluginDependency(dependency.trim()))
                        .collect(Collectors.toList()));
        // 设置配置文件名
        setIfNotEmpty(pluginDescriptor::setConfigFileName, properties.getProperty(CONFIG_FILE_NAME));
        // 设置配置文件激活列表
        List<String> configFileActives = properties.stringPropertyNames().stream()
                .filter(key -> key.startsWith(CONFIG_FILE_ACTIVE))
                .map(properties::getProperty)
                .collect(Collectors.toList());
        pluginDescriptor.setConfigFileActive(configFileActives.isEmpty() ?
                Collections.emptyList() :
                configFileActives);
        return pluginDescriptor;
    }

    public static DefaultPluginDescriptor storageDefaultPluginDescriptor(PluginSpecStorage pluginSpectStorage) {
        return new DefaultPluginDescriptor(pluginSpectStorage.getPluginId(),
                pluginSpectStorage.getPluginDescription(),
                pluginSpectStorage.getPluginClass(),
                pluginSpectStorage.getVersion(),
                pluginSpectStorage.getRequires(),
                pluginSpectStorage.getProvider(),
                pluginSpectStorage.getLicense());
    }

    public static OpsPluginDescriptor storageOpsPluginDescriptor(PluginSpecStorage pluginSpectStorage) {
        return new OpsPluginDescriptor(pluginSpectStorage.getPluginId(),
                pluginSpectStorage.getPluginDescription(),
                pluginSpectStorage.getPluginClass(),
                pluginSpectStorage.getVersion(),
                pluginSpectStorage.getRequires(),
                pluginSpectStorage.getProvider(),
                pluginSpectStorage.getLicense(),
                pluginSpectStorage.getConfigFileName(),
                pluginSpectStorage.getConfigFileActive());
    }

    /**
     * 如果值不为空，则调用 setter 方法设置值。
     *
     * @param setter 设置器方法引用
     * @param value  要设置的值
     */
    private static void setIfNotEmpty(PdcConsumer<String> setter, String value) {
        Optional.of(value).ifPresent(setter::accept);
    }

    @FunctionalInterface
    private interface PdcConsumer<T> {
        void accept(T t);
    }
}
