package com.sinotrans.transport.common.cache;

import com.sinotrans.transport.common.CommonConstant;
import com.sinotrans.transport.common.ErrorCode;
import com.sinotrans.transport.common.exception.CommonException;
import com.sinotrans.transport.common.util.MD5Utils;
import com.sinotrans.transport.dto.vo.CompanySimpleVo;
import com.sinotrans.transport.dto.vo.RoleMenuRespVo;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by emi on 2016/5/10.
 */
public class SingletonCache {

    private static Logger logger = Logger.getLogger(SingletonCache.class);
    private static ConcurrentHashMap<String, TokenCache> map = new ConcurrentHashMap();

    public static ConcurrentHashMap getMap() {
        return map;
    }

//    public static TokenCache putData(TokenCache tokenCache) {
//
//        map.putIfAbsent(tokenCache.getUserName(),tokenCache);
//        return map.get(tokenCache.getUserName());
//    }

    public static CheckResultVo checkToken(String userName, String token, String ipStr) {

        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userName)) {
            logger.error(" ---------- token: " + token + ",userName: " + userName);
            return new CheckResultVo(ErrorCode.NOT_LOGIN, "用户未登录，请先登录");
        }
        TokenCache tokenCache = map.get(userName);
        if (null == tokenCache) {
            logger.error(" ---------- 登录名：" + userName + "在 tokenCache 中不存在");
            return new CheckResultVo(ErrorCode.NAME_ERROR_REDIRECT_LOGIN, "用户未登录，请重新登录");
        }
        if (!token.equals(tokenCache.getToken())) {
            logger.error(" ---------- " + userName + "在 tokenCache 中的token是：" + tokenCache.getToken() + "，而传入的是：" + token);
            return new CheckResultVo(ErrorCode.TOKEN_ERROR_REDIRECT_LOGIN, "用户token不存在，请重新登录");
        }
        long timeInterval = System.currentTimeMillis() - tokenCache.getLastLoginTime();
        if (timeInterval > CommonConstant.TIME_INTERVAL) {
            logger.error(" ---------- " + userName + "距离上次访问的时间间隔是：" + timeInterval);
            return new CheckResultVo(ErrorCode.TOKEN_TIME_OUT,"用户离开太久，请重新登录");
        }
        if (StringUtils.isEmpty(ipStr)) {
            logger.error(" ---------- " + userName + "登录时未获取到ip地址");
            return new CheckResultVo(ErrorCode.IP_NULL, "请求相关信息获取失败，请重新登录");
        }
        if (!ipStr.equals(tokenCache.getIpStr())) {
            logger.error(" ---------- " + userName + "在 tokenCache 中的ip是：" + tokenCache.getIpStr() + "，而传入的是：" + ipStr);
            return new CheckResultVo(ErrorCode.IP_ERROR_REDIRECT_LOGIN, "用户IP异常，请重新登录");
        }

        updateCount(tokenCache);
        return new CheckResultVo(tokenCache.getUserId(), tokenCache.getCustomerType());
    }

    public static String putUpdateData(long userId, String userName, Integer customerType, String ipAddress, List<RoleMenuRespVo> authorities, List<Long> roleIdList, String companyName, String companyCode) {
        String md5Token;//todo:开发阶段给emi1和emi7走后门
        if ("emi1".equals(userName) || "emi7".equals(userName)) {
            md5Token = "T_emi_privilege";
        } else {
            md5Token = "T_" + MD5Utils.string2MD5(userName + System.currentTimeMillis());
        }
        if (0 == userId || StringUtils.isEmpty(userName) || StringUtils.isEmpty(ipAddress)) {
            throw new CommonException(ErrorCode.NULL_REGISTER_TOKEN_INFO,"令牌信息不能为空", "登录或注册时, userId userName ipAddress 其中之一为空", logger);
        }
        TokenCache tokenCache = map.get(userName);
        if (null != tokenCache) {
            tokenCache.updateSelf(userId, userName, customerType, md5Token, ipAddress, authorities, roleIdList, companyName,companyCode);
            map.replace(userName, tokenCache);
        } else {
            tokenCache = new TokenCache(userId, userName, customerType, md5Token, ipAddress, authorities, roleIdList, companyName, companyCode);
            map.put(userName, tokenCache);
        }
        return tokenCache.getToken();
    }

    private static void updateCount(TokenCache tokenCache) {
        tokenCache.setCount(new AtomicInteger(tokenCache.getCount().incrementAndGet()));
        tokenCache.setLastLoginTime(System.currentTimeMillis());
    }

    public static List<RoleMenuRespVo> getAuthorities(String key,String IpPort){
        if(null!=key&&null!=map&&null!=map.get(key)){
//            //权限变更
//            if(RoleInfoUtil.authorityHasChange&&map.get(key).getUserId()>0){
//                RestTemplate restTemplate = new RestTemplate();
//                String url = IpPort+RoleInfoUtil.authorityByUserUrl+map.get(key).getUserId()+"/"+RoleType.Customer.getValue();
//                AuthoritiesByUserResponse response = restTemplate.getForObject(url,AuthoritiesByUserResponse.class);
//                if(response.isSuccess()){
//                    map.get(key).setAuthorities(response.getAuthorities());
//                }
//            }
            return map.get(key).getAuthorities();
        }
        return null;
    }


    public static List<Long> getRoleIdList(String key) {
        if(null!=key&&null!=map&&null!=map.get(key)){
            return map.get(key).getRoleIdList();
        }
        return null;
    }

    public static CompanySimpleVo getCompanySimpleInfo(HttpServletRequest request){
        String userName = request.getHeader("userName");
        if(null!=userName&&null!=map&&null!=map.get(userName)){
            CompanySimpleVo vo = new CompanySimpleVo(map.get(userName).getCompanyName(),map.get(userName).getCompanyCode());
            if(null!=vo&&StringUtils.hasText(vo.getCompanyName())&&StringUtils.hasText(vo.getCompanyCode())){
                return vo;
            }
        }
        return null;
    }

}
