package com.yvan.springmvc;

import com.google.common.base.Strings;
import com.yvan.PageDb;
import com.yvan.platform.Conv;
import lombok.val;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;

/**
 * 用户的身份识别
 * Created by luoyifan on 2017/3/21.
 */
@Component
public class HttpUtils {

    public static final String TOKEN_KEY = "TOKEN";

    public static HttpServletRequest currentRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        } catch (Exception e) {
            return null;
        }
    }

    public static HttpServletResponse currentResponse() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
        } catch (Exception e) {
            return null;
        }
    }

    public static String currentRemoteIp() {
        HttpServletRequest request = currentRequest();
        if (request == null) {
            return "";
        }

        if (request.getHeader("x-forwarded-for") != null) {
            return request.getHeader("x-forwarded-for");
        }
        return request.getRemoteAddr();
    }

    public static String currentHost() {
        HttpServletRequest request = currentRequest();
        if (request == null) {
            return "";
        }

        String host = request.getHeader("X-Forwarded-Host");
        if (!Strings.isNullOrEmpty(host)) {
            return host;
        }
        return request.getHeader("Host");
    }

    public static String currentUrl() {
        HttpServletRequest request = currentRequest();
        if (request == null) {
            return "";
        }

        val url = request.getScheme() + "://" + currentHost() + request.getRequestURI();
        if (Strings.isNullOrEmpty(request.getQueryString())) {
            return url;
        }
        return url + "?" + request.getQueryString();
    }

    public static boolean isEqualPath(String s1, String s2) {
        if (Strings.isNullOrEmpty(s1) || Strings.isNullOrEmpty(s2)) {
            return false;
        }

        int p1 = s1.indexOf("?");
        if (p1 >= 0) {
            s1 = s1.substring(0, p1);
        }
        int p2 = s2.indexOf("?");
        if (p2 >= 0) {
            s2 = s2.substring(0, p1);
        }
        return s1.toLowerCase().equals(s2.toLowerCase());
    }

    public static String currentToken() {
        HttpServletRequest request = currentRequest();
        if (request == null) {
            return "";
        }

        String token;
        // 从head取
        token = request.getHeader(TOKEN_KEY);
        if (!Strings.isNullOrEmpty(token)) {
            return token;
        }

        // 从attribute取
        token = Conv.NS(request.getAttribute(TOKEN_KEY));
        if (!Strings.isNullOrEmpty(token)) {
            return token;
        }

        // 从cookie取
        token = getCookieValue(TOKEN_KEY);
        if (!Strings.isNullOrEmpty(token)) {
            return token;
        }

        return null;
    }

    public static void writeToken(String token) {
        Cookie cookie = new Cookie(TOKEN_KEY, token);
        cookie.setPath("/");
        writeCookie(cookie);
    }

    /**
     * 请求是否需要被拦截
     */
    public static boolean isFilterPass(HttpServletRequest httpRequest) {
        String thisUrl = httpRequest.getRequestURI();
        return (thisUrl.startsWith("/static/") ||
                thisUrl.startsWith("/manage/") ||
                thisUrl.startsWith("/druid/") ||
                thisUrl.startsWith("/igh2/") ||
                thisUrl.endsWith(".css") || thisUrl.endsWith(".jpg") || thisUrl.endsWith(".jpeg") ||
                thisUrl.endsWith(".html") || thisUrl.endsWith(".js") || thisUrl.endsWith(".png") ||
                thisUrl.endsWith(".gif") || thisUrl.endsWith(".map"));
    }

    /**
     * 从当前请求中获取分页方法和内容
     */
    public static PageDb parsePagination() {
        HttpServletRequest request = currentRequest();
        HttpParameterParser parser = HttpParameterParser.newInstance(request);
        int page = parser.getIntValue("page", 1);
        int start = parser.getIntValue("start", 0);
        int limit = parser.getIntValue("limit", 10);

        return new PageDb(page, limit);
    }


    /**
     * 得到当前request请求的所有cookie
     */
    public static Cookie[] getCookies() {
        HttpServletRequest request = currentRequest();
        return request == null ? null : request.getCookies();
    }

    /**
     * 根据cookie名字取得cookie
     */
    public static Cookie getCookie(String name) {
        Cookie[] cookies = getCookies();
        if (cookies != null && cookies.length > 0) {
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                String cookName = cookie.getName();
                if (cookName != null && cookName.equals(name)) {
                    return cookie;
                }
            }
        }
        return null;
    }

    public static String getCookieValue(String name) {
        Cookie cookie = getCookie(name);
        if (cookie == null) {
            return null;
        }
        return cookie.getValue();
    }

    /**
     * 将cookie写入客户端
     */
    public static void writeCookie(Cookie cookie) {
        if (cookie == null) return;
        HttpServletResponse response = currentResponse();

        /*
         * if (request != null) { String host = request.getHeader("Host"); if (ConfigUtils.WEBSITE.equals(host))
         * cookie.setDomain("." + ConfigUtils.DOMAIN); }
         */
        if (response != null) {
            response.addCookie(cookie);
        }
    }

    public static void removeCookie(String cookieName, String path) {

        HttpServletResponse response = currentResponse();
        HttpServletRequest request = currentRequest();

        removeCookie(request, response, cookieName, path);
    }

    public static void removeCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String path) {

        Cookie[] cookies = request.getCookies();
        if (cookies == null || cookies.length == 0) {
            return;
        }

        for (int i = 0; i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            if (cookie.getName().equals(cookieName)) {
                cookie.setMaxAge(0);
                cookie.setPath(path);
                response.addCookie(cookie);
                break;
            }
        }

    }

    public static String urlEncoding(String value) {
        try {
            byte[] bs = Base64.encodeBase64URLSafe(value.getBytes("UTF-8"));
            return new String(bs, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("encode error.", e);
        }
    }
}
