package com.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class LogUtils {
    public static String newLine = System.getProperty("line.separator");

    private List<String> requestLogCommon() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        List<String> logList = new LinkedList<>();
        logList.add("请求日志:");
        logList.add("url=" + request.getRequestURI());
        String accessToken = request.getHeader("access_token");
        logList.add("accessToken=" + accessToken);
        String method = request.getMethod();
        String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
        Map<String, String[]> map = request.getParameterMap();
        Map<String, Object> params = new LinkedHashMap<>();
        map.forEach((key, value) -> {
            Object object = value.length == 1 ? value[0] : Arrays.asList(value);
            params.put(key, object);
        });
        logList.add("paramData=" + JSON.toJSONString(params));
        if (HttpMethod.POST.name().equals(method) && null != contentType &&
                contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
            try (BufferedReader br = new BufferedReader(request.getReader())) {
                String paramData = br.readLine();
                logList.add("body=" + paramData);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logList.add("clientIp=" + IPUtils.getIpAddr(request));
        logList.add("HTTP_METHOD=" + method);

        return logList;
    }

    public void requestLog(Object result, long costTime) {
        List<String> logList = requestLogCommon();
        logList.add("返回内容:" + JSON.toJSONString(result, SerializerFeature.WriteDateUseDateFormat));
        String resultString = JSON.toJSONString(result);
        try {
            JSONObject resultJson = JSON.parseObject(resultString);
            if (resultJson.containsKey("errno")) {
                Integer errno = resultJson.getInteger("errno");
                if (errno == 0) {
                    logList.add(1, "请求开始:");
                    logList.add("请求耗时:" + costTime);
                    log.info(logList.stream().collect(Collectors.joining(newLine)));
                } else {
                    logList.add(1, "请求错误:");
                    log.warn(logList.stream().collect(Collectors.joining(newLine)));
                }
                return;
            }
        } catch (JSONException e) {
        }
    }

    public void requestLog(RuntimeException e) {
        if (e != null) {
            List<String> logList = requestLogCommon();
            logList.add(1, "请求异常:");
            logList.add("异常信息:");
            log.error(logList.stream().collect(Collectors.joining(newLine)), e);
        }
    }

    public void requestLog(Object result) {
        requestLog(result, 0);
    }
}