package com.dcsoft.system.face.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dcsoft.system.api.domain.SysOperLog;
import com.dcsoft.system.face.service.UnifyLogService;
import com.dcsoft.system.utils.HttpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 同一日志接入 服务层处理
 *
 * @author xueyi
 */
@Service
public class UnifyLogServiceImpl implements UnifyLogService {

    //是否开启
    //@Value("${unifyLog.unseal}")
    public Boolean unseal=false;

    //@Value("${unifyLog.url}")
    public String url;

   //@Value("${unifyLog.appKey}")
    public String appKey;

    //@Value("${unifyLog.appSecret}")
    public String appSecret;


    @Override
    public String writeLog(SysOperLog operLog) {
        String result="";
        if(unseal){
            Map<String, Object> headMap=new HashMap<String, Object>();
            String timestamp=new Date().getTime()+"";
            String sign= EncodeByMD5(appKey+timestamp+appSecret).toLowerCase();
            headMap.put("TimeStamp",timestamp);
            headMap.put("AppKey",appKey);
            headMap.put("Sign",sign);
            Map<String, Object> paramMap=new HashMap<String, Object>();
            JSONObject json=new JSONObject();
            json.put("userId","");//用户 ID，用户唯一标识
            json.put("realName",operLog.getOperName());//用户真实姓名
            json.put("reqeustUrl",operLog.getOperUrl());//用户请求的 URL
            json.put("requestTitle",operLog.getTitle());//用户操作名称（或调用的接口中文名称）
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            json.put("requestTime",sdf.format(operLog.getOperTime()));//请求时间格式：yyyy-MM-dd HH:mm:ss.SSS精确到毫秒
            json.put("userIpAddress",operLog.getOperIp());//用户请求的 IP 地址（最好是网络出口的 IP）
            if(operLog.getStatus()==0){
                json.put("respResult",true);//用户操作结果，true：成功，false：失败
            }else{
                json.put("respResult",false);//用户操作结果，true：成功，false：失败

            }
            Long time=operLog.getOperTime().getTime()+operLog.getCostTime();
            Date date =new Date(time);
            json.put("resultTime",sdf.format(date));//请 求 结 果 产 生 时 间 ， 格 式 ： yyyy-MM-ddHH:mm:ss.SSS，精确到毫秒
            try {
                InetAddress address = InetAddress.getLocalHost();
                json.put("serverIpAddress", address.getHostAddress());//后端应用所在服务器的内网 IP
            } catch (UnknownHostException e) {
                throw new RuntimeException(e);
            }
            json.put("sysCode","SYS0022");//日志接入方系统编码
            paramMap.put("logContent",json);
            paramMap.put("logFormatCode","LFM00002");
            result= HttpUtil.postData(url,headMap,paramMap);
        }
        return result;
    }

    /**
     * 对字符串进行32位MD5加密
     * @param str
     * @return
     */
    public static String EncodeByMD5(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes("UTF-8"));
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            String md5=new BigInteger(1, md.digest()).toString(16);
            //BigInteger会把0省略掉，需补全至32位
            return fillMD5(md5);
        } catch (Exception e) {
            throw new RuntimeException("MD5加密错误:"+e.getMessage(),e);
        }
    }

    private static String fillMD5(String md5) {
        //如果不够32位则回调自身补零，最后返回32位长度的签名
        return md5.length() == 32 ? md5 : fillMD5("0" + md5);
    }

}
