package com.ruoyi.common.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.text.Convert;

/**
 * 客户端工具类
 * 
 * @author ruoyi
 */
public class ServletUtils
{
    /**
     * 获取String参数
     */
    public static String getParameter(String name)
    {
        return getRequest().getParameter(name);
    }

    /**
     * 获取String参数
     */
    public static String getParameter(String name, String defaultValue)
    {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name)
    {
        return Convert.toInt(getRequest().getParameter(name));
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name, Integer defaultValue)
    {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取Boolean参数
     */
    public static Boolean getParameterToBool(String name)
    {
        return Convert.toBool(getRequest().getParameter(name));
    }

    /**
     * 获取Boolean参数
     */
    public static Boolean getParameterToBool(String name, Boolean defaultValue)
    {
        return Convert.toBool(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获得所有请求参数
     *
     * @param request 请求对象{@link ServletRequest}
     * @return Map
     */
    public static Map<String, String[]> getParams(ServletRequest request)
    {
        final Map<String, String[]> map = request.getParameterMap();
        return Collections.unmodifiableMap(map);
    }

    /**
     * 获得所有请求参数
     *
     * @param request 请求对象{@link ServletRequest}
     * @return Map
     */
    public static Map<String, String> getParamMap(ServletRequest request)
    {
        Map<String, String> params = new HashMap<>();
        for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
        {
            params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
        }
        return params;
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest()
    {
        return getRequestAttributes().getRequest();
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse()
    {
        return getRequestAttributes().getResponse();
    }

    /**
     * 获取session
     */
    public static HttpSession getSession()
    {
        return getRequest().getSession();
    }

    public static ServletRequestAttributes getRequestAttributes()
    {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 将字符串渲染到客户端
     * 
     * @param response 渲染对象
     * @param string 待渲染的字符串
     */
    public static void renderString(HttpServletResponse response, String string)
    {
        try
        {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 是否是Ajax异步请求
     * 
     * @param request
     */
    public static boolean isAjaxRequest(HttpServletRequest request)
    {
        String accept = request.getHeader("accept");
        if (accept != null && accept.contains("application/json"))
        {
            return true;
        }

        String xRequestedWith = request.getHeader("X-Requested-With");
        if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
        {
            return true;
        }

        String uri = request.getRequestURI();
        if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
        {
            return true;
        }

        String ajax = request.getParameter("__ajax");
        return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
    }

    /**
     * 内容编码
     * 
     * @param str 内容
     * @return 编码后的内容
     */
    public static String urlEncode(String str)
    {
        try
        {
            return URLEncoder.encode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return StringUtils.EMPTY;
        }
    }

    /**
     * 内容解码
     * 
     * @param str 内容
     * @return 解码后的内容
     */
    public static String urlDecode(String str)
    {
        try
        {
            return URLDecoder.decode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return StringUtils.EMPTY;
        }
    }

    /**
     * 前端是否请求翻译字典
     * translate_dict: bool 1/Y/yes/true/translate_dict, 为真则前端请求翻译内容
     * translate_dict_backup_raw: bool 1/Y/yes/true/translate_dict_backup_raw, 为真则前端请求保留字典原值到params(仅对返回BaseEntity有效)
     */
    public static boolean requestTranslateData(boolean[]... args /* = 0: 返回前端是否请求需要保留字典原值到params(仅对返回BaseEntity有效) */)
    {
        String translate_dict = ServletUtils.getRequest().getParameter("translate_dict");
        if(StringUtils.isEmpty(translate_dict))
            return false;
        boolean res = "translate_dict".equalsIgnoreCase(translate_dict)
                || "y".equalsIgnoreCase(translate_dict)
                || "yes".equalsIgnoreCase(translate_dict)
                || "true".equalsIgnoreCase(translate_dict)
                || "1".equalsIgnoreCase(translate_dict)
                ;
        if (res && null != args && args.length > 0 && args[0].length > 0) {
            String translate_dict_backup_raw = ServletUtils.getRequest().getParameter("translate_dict_backup_raw");
            if(StringUtils.isNotEmpty(translate_dict_backup_raw))
            {
                args[0][0] = "translate_dict_backup_raw".equalsIgnoreCase(translate_dict_backup_raw)
                        || "y".equalsIgnoreCase(translate_dict_backup_raw)
                        || "yes".equalsIgnoreCase(translate_dict_backup_raw)
                        || "true".equalsIgnoreCase(translate_dict_backup_raw)
                        || "1".equalsIgnoreCase(translate_dict_backup_raw)
                        ;
            }
        }
        return res;
    }

    // @XXXMapping(value = "/xxx/**") 取**占位的字符串
    public static String getPathVariable() {
        HttpServletRequest request = getRequest();
        String path = (String) request.getAttribute("org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping" /*HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE*/);
        String matchPattern = (String) request.getAttribute("org.springframework.web.servlet.HandlerMapping.bestMatchingPattern" /*HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE*/);
        return new AntPathMatcher().extractPathWithinPattern(matchPattern, path);
    }
}
