package cn.estsh.i3plus.pojo.base.bean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;

/**
 * @Description : 本地线程，用于保存用户临时数据（按线程生命周期保存）
 * 需要在线程结束的地方调用removeThreadLocal（），防止内存泄漏
 * @Reference : 生命周期：一次controller请求
 * @Author :  alwaysfrin
 * @CreateDate : 2020-08-24 20:49
 * @Modify:
 **/
public class BaseThreadLocal {
    public static final Logger LOGGER = LoggerFactory.getLogger(BaseThreadLocal.class);

    /*private static final ThreadLocal<HashMap<String,Object>> dataThredLocal = new ThreadLocal(){
        @Override
        protected HashMap<String,Object> initialValue() {
            //每个线程初始化map
            return new HashMap<String,Object>();
        }
    };*/
    private static final ThreadLocal<HashMap<String,Object>> DATA_THREAD_LOCAL = ThreadLocal.withInitial(() -> new HashMap<>());

    public static Object getData(String key) {
        if(DATA_THREAD_LOCAL.get() != null) {
            return DATA_THREAD_LOCAL.get().get(key);
        }else{
            return null;
        }
    }

    public static String getDataStr(String key) {
        Object data = getData(key);
        if(data != null){
            return data.toString();
        }else{
            return null;
        }
    }

    public static int getDataInt(String key) {
        Object data = getData(key);
        if(data != null){
            return Integer.parseInt(data.toString());
        }else{
            return 0;
        }
    }

    public static long getDataLong(String key) {
        Object data = getData(key);
        if(data != null){
            return Long.parseLong(data.toString());
        }else{
            return 0L;
        }
    }

    public static double getDataDouble(String key) {
        Object data = getData(key);
        if(data != null){
            return Double.parseDouble(data.toString());
        }else{
            return 0.0;
        }
    }

    public static void setData(String name, Object value) {
        //不需要主数据源开始，则自动切换
        DATA_THREAD_LOCAL.get().put(name, value);
    }

    /**
     * 手动再次清除线程变量
     * 需要在方法后调用，或者通过ascept拦截后进行清空
     */
    public static void removeThreadLocal(){
        if(DATA_THREAD_LOCAL != null) {
            if (DATA_THREAD_LOCAL.get() != null) {
                //清空数据
                DATA_THREAD_LOCAL.get().clear();
            }
            //移除当前线程信息
            DATA_THREAD_LOCAL.remove();
        }
    }

    public static String getInfo(){
        Thread thread = Thread.currentThread();
        return "thead-id:" + thread.getId() + ",thread:" + thread;
    }

    public static void printDetail(){
        LOGGER.info("========本地线程临时数据=======");
        LOGGER.info("数据数量：{}", DATA_THREAD_LOCAL.get().size());
        for(String key : DATA_THREAD_LOCAL.get().keySet()){
            LOGGER.info("key:{},value:{}",key, DATA_THREAD_LOCAL.get().get(key));
        }
    }

    /********* 用户信息 **********/
    public static final String INIT_INFO = "INIT_INFO";  //初始化数据
    public static final String EMP_NAME = "USER_NAME";    //用户名
    public static final String ORGANIZE_CODE = "ORGANIZE_CODE";    //组织代码
    public static final String LANGUAGE_CODE = "LANGUAGE_CODE";    //语言代码

    public static boolean isInit(){
        Object data = getData(INIT_INFO);
        if(data != null){
            return Boolean.parseBoolean(data.toString());
        }else{
            return false;
        }
    }

    //初始化用户数据
    public static void initSessionUserThreadLocal(String empName, String organizeCode,String languageCode){
        setData(BaseThreadLocal.EMP_NAME, empName);
        setData(BaseThreadLocal.ORGANIZE_CODE, organizeCode);
        setData(BaseThreadLocal.LANGUAGE_CODE, languageCode);
        setData(BaseThreadLocal.INIT_INFO, true);
    }

    //获取线程中的人员姓名
    public static String getThreadEmpName(){
        String empName = getDataStr(EMP_NAME);
        if(empName == null){
            empName = "系统";
        }
        return empName;
    }
    //获取线程中的组织代码
    public static String getThreadOrganizeCode(){
        String organizeCode = getDataStr(ORGANIZE_CODE);
        if(organizeCode == null){
            organizeCode = "-1";
        }
        return organizeCode;
    }
    //获取线程中的语言代码
    public static String getThreadLanguageCode(){
        String organizeCode = getDataStr(LANGUAGE_CODE);
        if(organizeCode == null){
            organizeCode = "CN/zh";
        }
        return organizeCode;
    }
}
