package cn.axzo.workflow.core.version;


import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.axzo.workflow.core.version.Versioned.UNKNOWN_VERSION;

public class MultiVersionBeanUtils {

    /**
     * 获取支持指定版本的bean
     *
     * @param clazz   类型
     * @param version 版本号
     * @param <T>
     * @return
     */
    public static <T extends Versioned> T getSpecifiedVersionBean(Class<T> clazz, String version) {
        Map<String, T> beans = SpringContextUtils.getBeansOfType(clazz);
        if (CollectionUtils.isEmpty(beans)) {
            throw new NullPointerException("no beans of type " + clazz.getName());
        }
        if (StringUtils.isEmpty(version)) {
            T t = beans.values().stream().filter(bean -> bean.getVersion() == null || bean.getVersion() == UNKNOWN_VERSION).findFirst().orElse(null);
            if (t != null) {
                return t;
            }
            throw new IllegalArgumentException("no default version bean found for version: " + version);
        }
        //根据版本号排序
        List<T> sortedList = beans.values().stream().sorted((o1, o2) -> {
            DefaultArtifactVersion version1 = o1.getVersion() == null ? UNKNOWN_VERSION : o1.getVersion();
            DefaultArtifactVersion version2 = o2.getVersion() == null ? UNKNOWN_VERSION : o2.getVersion();
            return version1.compareTo(version2);
        }).collect(Collectors.toList());
        DefaultArtifactVersion targetVersion = new DefaultArtifactVersion(version);
        for (int i = sortedList.size() - 1; i >= 0; i--) {
            DefaultArtifactVersion classVersion = sortedList.get(i).getVersion() == null ? UNKNOWN_VERSION : sortedList.get(i).getVersion();
            int flag = classVersion.compareTo(targetVersion);
            if (flag <= 0) {
                return sortedList.get(i);
            }
        }
        throw new NullPointerException("no beans of type " + clazz.getName() + " and version " + version);
    }
}
