package com.duiba.tuia.youtui.web.tool;

import com.duiba.tuia.youtui.web.constant.Constants;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

import cn.com.duiba.wolf.utils.UrlUtils;

/**
 * 如果是Grails进入的请求，某些测试可以使用下面的方法获取: There is a new forwardURI property using request.forwardURI and you can obtain other
 * props using standard servlet request attributes: public static final String FORWARD_REQUEST_URI_ATTRIBUTE =
 * "javax.servlet.forward.request_uri"; public static final String FORWARD_CONTEXT_PATH_ATTRIBUTE =
 * "javax.servlet.forward.context_path"; public static final String FORWARD_SERVLET_PATH_ATTRIBUTE =
 * "javax.servlet.forward.servlet_path"; public static final String FORWARD_PATH_INFO_ATTRIBUTE =
 * "javax.servlet.forward.path_info"; public static final String FORWARD_QUERY_STRING_ATTRIBUTE =
 * "javax.servlet.forward.query_string";
 * 
 * @author xuhengfei
 */
public class RequestTool {


    private static ThreadLocal<HttpServletRequest> request   = new ThreadLocal<>();
    private static final String                    LOCALHOST = "127.0.0.1";
    private static final String                    IPHONE    = "iphone";
    private static final String                    ANDROID   = "android";
    private static final String                    WINDOWS   = "windows";
    private static final String                    LINUX     = "linux";
    private static final String                    MAC       = "macintosh";
    private static final String                    IPAD      = "ipad";
    private static final String                    IOS       = "ios";
    private static final String                    UA        = "User-Agent";
    private static final String                    UNKNOWN   = "unknown";
    /**
     * 维护一个静态map，手机的操作系统
     */
    private static final Map<String, String>       osMap     = new HashMap<>();
    static {
        osMap.put("iPad", IPAD);
        osMap.put("iPhone", IPHONE);
        osMap.put("Windows", WINDOWS);
        osMap.put("Mac", MAC);
        osMap.put("Android", ANDROID);
        osMap.put("Linux", LINUX);
    }

    private RequestTool() {
    }

    /**
     * getHttpServletRequest:(这里用一句话描述这个方法的作用). <br/>
     * 
     * @return
     * @since JDK 1.6
     */
    public static HttpServletRequest getHttpServletRequest() {
        return request.get();
    }

    /**
     * setRequestInThreadLocal:(这里用一句话描述这个方法的作用). <br/>
     * 
     * @param req
     * @since JDK 1.6
     */
    public static void setRequestInThreadLocal(HttpServletRequest req) {
        request.set(req);
    }

    /**
     * 获取操作系统类型： Android,iPhone,iPad,Mac,Windows,Linux
     * 
     * @param request
     * @return
     */
    public static String getOSNew(HttpServletRequest request) {
        Map<String, String> phoneMap = new HashMap<>();
        phoneMap.put(IPHONE, "1");
        phoneMap.put(ANDROID, "0");
        phoneMap.put(LINUX, "5");
        phoneMap.put(WINDOWS, "2");
        phoneMap.put(MAC, "3");
        phoneMap.put(IOS, "6");
        phoneMap.put(IPAD, "4");
        String ua = request.getHeader(UA);
        if (ua != null) {
            return getValueFromMap(phoneMap, ua);
        }
        return "6";
    }

    /**
     * getIpAddr:(这里用一句话描述这个方法的作用). <br/>
     * 
     * @param request
     * @return
     * @since JDK 1.6
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip != null && ip.trim().length() > 0) {
            String[] ips = ip.trim().split(",");
            int size = ips.length;
            if (size > 0) {
                ip = ips[0].trim();
            }
        }
        ip = getIp(request, ip);
        if (ip != null && ip.startsWith("0:0:0:0")) {
            ip = LOCALHOST;
        }
        return ip;
    }

    private static String getIp(HttpServletRequest request, String ip) {
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Cdn-Src-Ip");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    /**
     * 获取操作系统类型： Android,iPhone,iPad,Mac,Windows,Linux
     * 
     * @param request
     * @return
     */
    public static String getOS(HttpServletRequest request) {
        String ua = request.getHeader(UA);
        if (ua == null) {
            return UNKNOWN;
        }
        return getValueFromMap(osMap, ua.toLowerCase());
    }

    /**
     * getCookie:(这里用一句话描述这个方法的作用). <br/>
     * 
     * @param request
     * @param name
     * @return
     * @since JDK 1.6
     */
    public static String getCookie(HttpServletRequest request, String name) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie c : cookies) {
                if (name.equals(c.getName())) {
                    String value = c.getValue();
                    if (value != null && value.length() > 0) {
                        return value;
                    }
                }
            }
        }
        return null;
    }

    /**
     * getUserAgent:(这里用一句话描述这个方法的作用). <br/>
     * 
     * @param request
     * @return
     * @since JDK 1.6
     */
    public static String getUserAgent(HttpServletRequest request) {
        return request.getHeader(UA);
    }

    /**
     * getUserAgent:获取User-Agent.
     *
     * @param ua the ua
     * @return the UA
     * @author clemac
     * @since JDK 1.6
     */
    public static String getUA(String ua) {
        if (ua == null) {
            return UNKNOWN;
        }
        String uaNew = ua.toLowerCase();
        if (uaNew.contains(IPHONE) || uaNew.contains(IPAD) || uaNew.contains(MAC)) {
            return "IOS";
        } else if (uaNew.contains(ANDROID)) {
            return "Android";
        }
        return UNKNOWN;
    }

    /**
     * 抽象一个公共方法，用来输入map，输出对应的String
     * 
     * @param map
     * @param ua
     * @return
     */
    private static String getValueFromMap(Map<String, String> map, String ua) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            if (ua.toLowerCase().contains(key)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * 从Referer中获取参数
     * @param request request
     * @param name 参数名称
     * @return 参数值
     */
    public static String getParamFromReferer(HttpServletRequest request, String name) {
        String referer = request.getHeader(Constants.HTTPHEADER.REFERER);
        Map<String, String> params = UrlUtils.uRLRequest(referer);
        return params.get(name);
    }
}
