package cn.pluss.platform.service;

import cn.jiguang.common.utils.StringUtils;
import cn.pluss.platform.entitiy.UnknownException;
import cn.pluss.platform.mapper.UnknownExceptionMapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;


@Service
public class UnknownExceptionService extends ServiceImpl<UnknownExceptionMapper, UnknownException> {

    /**
     * 保存异常信息到数据库
     * @param e
     */
    public void save(HttpServletRequest request, Exception e) {
        String body = null;
        try {
            InputStream is = request.getInputStream();
            StringBuilder responseStrBuilder = new StringBuilder();
            BufferedReader streamReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null) {
                responseStrBuilder.append(inputStr);
            }
            body = responseStrBuilder.toString();
        } catch (Exception ignored) {
            // 不处理
        }

        Map<String, Object> parameterInfo = getParameterInfo(request);
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        UnknownException unknownException = new UnknownException();
        unknownException.setCreateTime(new Date());
        unknownException.setName(e.getClass().getName());
        String desc = sw.toString();

        Map<String, Object> headerInfo = getHeaderInfo(request);
        try {
            String userId = headerInfo.get("userId") + "";
            unknownException.setUserId(Long.parseLong(userId));
        } catch (Exception e2) {
            log.warn("没有userId");
        }

        if (StringUtils.isNotEmpty(body)) {
            unknownException.setParams(body);
        } else {
            unknownException.setParams(JSON.toJSONString(parameterInfo));
        }
        unknownException.setUri(request.getRequestURI());
        unknownException.setDesc(desc);
        baseMapper.insert(unknownException);
    }

    /**
     * 保存异常信息到数据库
     * @param e 异常信息
     */
    public void save(Exception e) {
        String desc = getStackTrace(e);
        UnknownException unknownException = new UnknownException();
        unknownException.setCreateTime(new Date());
        unknownException.setName(e.getClass().getName());
        unknownException.setDesc(desc);
        baseMapper.insert(unknownException);
    }

    private String getStackTrace(Exception e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        return sw.toString();
    }

    private Map<String, Object> getParameterInfo(HttpServletRequest request) {
        Map<String, Object> parameter = new HashMap<>();
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry: parameterMap.entrySet()) {
            String key = entry.getKey();
            String[] parameterValues = entry.getValue();
            if (parameterValues.length == 1) {
                parameter.put(key, parameterValues[0]);
            } else {
                parameter.put(key, Arrays.toString(parameterValues));
            }
        }
        return parameter;
    }

    private Map<String, Object> getHeaderInfo(HttpServletRequest request) {
        Map<String, Object> parameter = new HashMap<>(8);
        Enumeration<String> headerNames = request.getHeaderNames();

        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            parameter.put(key, request.getHeader(key));
        }

        return parameter;
    }
}
