package com.face.util;

import com.google.common.collect.Lists;
import com.face.global.consts.GlobalConstant;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;

import java.net.InetAddress;
import java.util.*;

@Slf4j
public class HttpUtils {
    public static Map getHeadersInfo(HttpServletRequest request, HttpHeaders headers) {
        Map datas = new HashMap();
        if (headers != null) {
            headers.entrySet().forEach(stringListEntry ->
                    datas.put(stringListEntry.getKey(), stringListEntry.getValue()));
        } else {
            Enumeration<String> keys = request.getHeaderNames();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();
                datas.put(key, Lists.newArrayList(request.getHeaders(key).asIterator()));
            }
        }
        datas.remove(GlobalConstant.TOKEN_KEY);
        datas.remove(GlobalConstant.TOKEN_KEY.toLowerCase(Locale.ROOT));
        return datas;
    }

    public static String getUri(ServletRequest servletRequest) {
        if (servletRequest instanceof HttpServletRequest) {
            return ((HttpServletRequest) servletRequest).getRequestURI();
        }
        return servletRequest.getRequestId();
    }

    public static Map<String, String[]> getParams(ServletRequest servletRequest) {
        return servletRequest.getParameterMap();
    }

    public static Map getHeaders(ServletRequest servletRequest) {
        if (servletRequest instanceof HttpServletRequest) {
            return getHeadersInfo((HttpServletRequest) servletRequest, null);
        }
        return new HashMap<>();
    }


    public static Map getHeaders(ServletResponse servletResponse) {
        if (servletResponse instanceof HttpServletResponse) {
            return getHeadersInfo((HttpServletResponse) servletResponse);
        }
        return new HashMap<>();
    }

    public static Map getHeadersInfo(HttpServletResponse response) {
        Map datas = new HashMap();
        Collection<String> keys = response.getHeaderNames();
        for (String key : keys) {
            datas.put(key, response.getHeaders(key));
        }
        datas.remove(GlobalConstant.TOKEN_KEY);
        return datas;
    }

    public static void addHeader(ServletResponse servletResponse, String key, String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return;
            }
            if (servletResponse instanceof HttpServletResponse) {
                ((HttpServletResponse) servletResponse).addHeader(key, id);
            }
        } catch (Exception e) {

        }
    }

    public static String getReqIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (StringUtils.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip)
                && StringUtils.contains(ip, ",")) {
            // 多次反向代理后会有多个IP值，第一个为真实IP。
            ip = StringUtils.substringBefore(ip, ",");
        }
        // 处理localhost访问
        if (StringUtils.isBlank(ip) || "unkown".equalsIgnoreCase(ip) || StringUtils.split(ip, ".").length != 4) {
            try {
                InetAddress inetAddress = InetAddress.getLocalHost();
                ip = inetAddress.getHostAddress();
            } catch (Exception e) {
            }
        }
        return ip;
    }

}
