package com.ssj.framework.core.util;

import com.alibaba.fastjson.JSONObject;
import com.ssj.framework.basic.config.bean.VersionConfig;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;


/**
 * 
 * 类名称：SystemResourceLocator<br>
 * 类描述：系统属性资源存储类.<br>
 * 便于在其他地方调用,但添加的时候不能有重名.除非显示调用需要覆盖的接口<br>
 * @version v1.0
 *
 */

@Component
public class SystemResourceLocator implements ApplicationContextAware {



    /**
     * spring的容器上下文
     */
    private static ApplicationContext context;

    /**
     * 实例化,执行非静态变量块
     */
    private static SystemResourceLocator instance = new SystemResourceLocator();



    public   static RedisUtil redisUtil=null;


    private static String versionKey="VERSION_*";


    public static final SystemResourceLocator getInstance() {
        return instance;
    }
    @PostConstruct
    public void  init() {
        //启动各子项目时：全量添加到redis，为保证数据的统一，覆盖旧数据，其它系统更新配置的时候一定要先同步更新到数据库
        redisUtil= (RedisUtil)SystemResourceLocator.getBean(RedisUtil.class);

    }
    /**
     * 取指定科目的版本列表
     * @param courseName
     * @return
     */
    public synchronized static Map<String,List<VersionConfig>>  getVersionList(String courseName) {

        Map<String,List<VersionConfig>> maps=new LinkedHashMap<String, List<VersionConfig>>();
        TreeSet<String> keys=redisUtil.keys(versionKey);
        for (String key : keys) {
            try {
                if (redisUtil.exists(key.toString())){
                    String result = redisUtil.get(key.toString());
                    if(StringUtil.isNotEmpty(result)){
                        VersionConfig versionConfig=JSONObject.parseObject(result, VersionConfig.class);
                        if(StringUtil.isNotEmpty(courseName)){
                            if(!courseName.equals(versionConfig.getCourseName())){
                                continue;
                            }
                        }
                        if(maps.containsKey(versionConfig.getCourseName())){
                            maps.get(versionConfig.getCourseName()).add(versionConfig);
                        }else{
                            List<VersionConfig> list=new ArrayList<VersionConfig>();
                            list.add(versionConfig);
                            maps.put(versionConfig.getCourseName(), list);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return maps;
    }

    /**
     * 取全部科目的版本列表
     * @param
     * @return
     */
    public synchronized static Map<String,List<VersionConfig>>  getVersionList() {
        return getVersionList(null);
    }


    /**
     * 取值
     * @param key
     * @return
     */
    public synchronized static Object getValue(Object key) {

        Object result = null;
        if (redisUtil.exists(key.toString())){
            result = redisUtil.get(key.toString());
        }

        return result;
    }



    /**
     * 添加系统属性
     * @param key
     * @param value
     */
    public synchronized static void setValue(Object key, Object value) {
        setValue(key, value, false);
    }

    /**
     * 添加系统属性
     * @param key
     * @param value
     * @param isCover 是否可以覆盖
     */
    public synchronized static void setValue(Object key, Object value, boolean isCover) {
        if (!isCover && redisUtil.exists(key.toString())) {
            throw new RuntimeException("系统已存在属性" + key + ",不能覆盖该项值.");
        }else {
            redisUtil.set(key.toString(), value.toString());
        }
    }

   



    @Override
    public void setApplicationContext(ApplicationContext contex) throws BeansException{
        SystemResourceLocator.context = contex;
    }

    /**
     * 通过bean名称获取bean
     * @param beanName
     * @return
     */
    public synchronized static Object getBean(String beanName) {
        return context.getBean(beanName);
    }


    /**
     * 通过class名称获取bean
     * @param
     * @return
     */
    public static <T> T getBean(Class<T> requiredType) {
        return getBean(requiredType,"1.0");
    }

    public static <T> T getBean(Class<T> requiredType,String version) {

        return context.getBean(requiredType);
    }


    /**
     * 通过bean名称及类型获取bean
     * @param beanName
     * @param requiredType
     * @return
     */
    public synchronized static Object getBean(String beanName, Class<?> requiredType) {
        return context.getBean(beanName, requiredType);
    }

}
