package com.philisense.www.access;

import com.philisense.www.core.text.Convert;
import com.philisense.www.dao.JwtPermissionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.*;


@Service
public class WebRestURLSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    private static final Logger log = LoggerFactory.getLogger(WebRestURLSecurityMetadataSource.class);

    @Autowired
    private JwtPermissionDAO jwtPermissionDAO;

    public static HashMap<String, Collection<ConfigAttribute>> map = null;

    public void reLoadResource() {
        loadResourceDefine();
    }

    Collection<ConfigAttribute> configAttributes;

    @PostConstruct
    public void loadResourceDefine() {
        map = new HashMap<>();

        ConfigAttribute cfg;
        Map<String, Object> vars = new HashMap<>();
        vars.put("res_type", "A");
        vars.put("systemid", "000000000000");
        Set<Map<String, Object>> permissions = jwtPermissionDAO.getAllUrlResources(vars);

        for (Map<String, Object> permission : permissions) {
            String href = Convert.toStr(permission.get("href"), "");
            String authority= Convert.toStr(permission.get("authority"), "ROLE_NO_PERMISSION");

            configAttributes = new ArrayList<>();
            cfg = new SecurityConfig(authority);
            configAttributes.add(cfg);

            if (map.containsKey(href)) {
                Collection<ConfigAttribute> newconfigAttributes = map.get(href);
                if (null != newconfigAttributes && newconfigAttributes.contains(new SecurityConfig(authority)))
                    continue;
                ConfigAttribute newconfigAttribute = new SecurityConfig(authority);
                newconfigAttributes.add(newconfigAttribute);
                map.put(href, newconfigAttributes);
                log.info("{} ----------------permission.get(\"href\")---------------------{}", newconfigAttributes, permission.get("href"));
            } else {
                map.put(href, configAttributes);
                log.info("{} ----------------permission.get(\"href\")---------------------{}", configAttributes, permission.get("href"));
            }
        }
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        if (map == null) loadResourceDefine();
        FilterInvocation filterInvocation = (FilterInvocation) object;
        HttpServletRequest request = filterInvocation.getRequest();
        String servletPath = request.getServletPath();

        if (null != servletPath && "" != servletPath) {
            String temp[] = servletPath.split("\\?");
            if (null != temp && temp.length > 0) {
                servletPath = temp[0];
            }
        }
        if (null == map.get(servletPath)) {
            List<ConfigAttribute> co = new ArrayList<>();
            co.add(new SecurityConfig("ROLE_NEVER_EXIST"));//传一个永远不存在的角色ROLE_NEVER_EXIST
            return co;
        }

        return map.get(servletPath);
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return configAttributes;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}