package com.example.demo.security;

import ch.qos.logback.core.joran.conditional.ElseAction;
import com.example.demo.config.HttpSessionConfig;
import com.example.demo.config.entity.UserElement;
import com.example.demo.constant.Constants;
import com.example.demo.constant.Header;
import com.example.demo.constant.Status;
import com.example.demo.dto.RoleDTO;
import com.example.demo.entity.ToSysMenu;
import com.example.demo.service.IRoleService;
import com.example.userserver.entity.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 预授权
 * @author weiximei
 */
public class RestAbstractPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {

    private AntPathMatcher matcher = new AntPathMatcher();

    private IRoleService iRoleService;


    /** 用户类型请求登陆类型 **/
    private String loginType;

    /**
     * 不需要权限访问的路径
     */
    private List<ToSysMenu> noneSecurity;

    /**
     * 获取主体信息
     *
     *      1.验证是否有权限
     *      2.授权
     *
     * @param request
     * @return
     */
    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
        // 不需要的拦截请求处理
        if (isNoneSecurity(request.getRequestURI().toString()) || "OPTIONS".equals(request.getMethod())){
            GrantedAuthority[] authorities = new GrantedAuthority[1];
            GrantedAuthority roleNone = new SimpleGrantedAuthority(Constants.ROLE_NONE);
            authorities[0]=roleNone;
            grantedAuthorityList.add(authorities[0]);
            return new TokenAuthrentication(grantedAuthorityList);
        }

        isInspection(request);

        if (null == request.getAttribute(Header.HEADER_ERROR.getValue())){
            try {
                UserElement userElement = getUserElement(loginType, request);
                List<RoleDTO> roleDTOList = iRoleService.getUserRoleByUserId(userElement.getId());
                grantedAuthorityList = roleDTOList.stream()
                        .map(e->new SimpleGrantedAuthority(e.getRoleName().trim()))
                        .collect(Collectors.toList());
            } catch (Exception e){
                System.out.println("用户授权失败!");
                e.printStackTrace();
            }

        }else {
            // 校验有问题后, 需要给个角色, 让流程继续下去
            GrantedAuthority[] authorities = new GrantedAuthority[1];
            GrantedAuthority roleNone = new SimpleGrantedAuthority("ROLE_NONE");
            authorities[0]=roleNone;
            grantedAuthorityList.add(authorities[0]);
        }

        return new TokenAuthrentication(grantedAuthorityList);
    }


    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest httpServletRequest) {
        return null;
    }

    /**
     * 验证url是否是不需要权限访问
     * @param url
     * @return
     */
    private boolean isNoneSecurity(String url){
        for (ToSysMenu sysMenu : noneSecurity) {
            if (matcher.match(sysMenu.getMenuUrl(),url)){
                return true;
            }
        }
        return false;
    }

    /**
     * 检验Token, App版本, 用户登录类型
     * @param request
     */
    private void isInspection(HttpServletRequest request){
        // Token检测
        String token = request.getHeader(Header.REQUEST_X_AUTH_TOKEN.getValue()).trim();
        if (StringUtils.isNotBlank(token)) {
            request.setAttribute(Header.HEADER_ERROR.getValue(), Status.RESPONSE_STATUS_802.getValue());
        }
        // APP版本检测
        String version = request.getHeader(Header.REQUEST_VERSION.getValue()).trim();
        if (StringUtils.isBlank(version)){
            request.setAttribute(Header.HEADER_ERROR.getValue(),Status.RESPONSE_STATUS_800.getValue());
        }
        // 用户登陆类型检测
        loginType = ((String) request.getAttribute(Header.LOGIN_TYPE.getValue())).trim();
        if (StringUtils.isBlank(loginType)) {
            request.setAttribute(Header.HEADER_ERROR.getValue(),Status.RESPONSE_STATUS_801.getValue());
        }
    }


    /**
     * 获取用户session信息
     * @param loginType 用户类型
     * @param request
     * @return
     */
    public UserElement getUserElement(String loginType, HttpServletRequest request){
        HttpSession session = request.getSession();
        UserElement userElement = null;
        if ("app".equals(loginType)) {
            userElement = (UserElement) session.getAttribute(Constants.APP_USER_SESSION);
        } else if ("web".equals(loginType)) {
            userElement = (UserElement) session.getAttribute(Constants.WEB_USER_SESSION);
        }

        return userElement;
    }

}
