package com.uas.platform.b2b.support;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
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.security.web.util.matcher.AntPathRequestMatcher;

import com.uas.platform.b2b.dao.ResourceDao;
import com.uas.platform.b2b.model.Resource;

/**
 * 资源数据定义，将所有的资源和权限对应关系建立起来，即定义某一资源可以被哪些角色访问
 * 
 * @author yingp
 * @version 1.0
 */
public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	@Autowired
	private ResourceDao resourceDao;

	/**
	 * LOGGER 日志对象
	 */
	private final static Logger LOGGER = Logger.getLogger(CustomSecurityMetadataSource.class);

	private HashMap<String, Collection<ConfigAttribute>> resourceMap;

	/**
	 * 加载资源，初始化资源变量
	 * 
	 */
	private void loadResourceDefine() {
		if (resourceMap == null) {
			resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
			List<Resource> resources = resourceDao.findAll();
			for (Resource resource : resources) {
				Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
				ConfigAttribute configAttribute = new SecurityConfig(resource.getName());
				configAttributes.add(configAttribute);
				resourceMap.put(resource.getMethod() + ":" + resource.getUrl(), configAttributes);
			}
		}
	}

	public CustomSecurityMetadataSource() {

	}

	/**
	 * 根据路径获取访问权限的集合接口
	 * 
	 * @param object
	 * @return
	 * @throws IllegalArgumentException
	 */
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

		LOGGER.info(object);
		if (resourceMap == null)
			loadResourceDefine();
		HttpServletRequest request = ((FilterInvocation) object).getRequest();
		for (Iterator<String> iter = resourceMap.keySet().iterator(); iter.hasNext();) {
			String resourceKey = iter.next();
			String[] resourceParam = resourceKey.split(":");
			String resourceMethod = resourceParam[0];
			String resourceUrl = resourceParam[1];
			AntPathRequestMatcher matcher = new AntPathRequestMatcher(resourceUrl);
			if (null != resourceUrl && request.getMethod().equals(resourceMethod) && matcher.matches(request)) {
				return resourceMap.get(resourceKey);
			}
		}
		return null;
	}

	public String getRequestPath(HttpServletRequest request) {
		String url = request.getServletPath();
		if (request.getPathInfo() != null)
			url = url + request.getPathInfo();
		return url;
	}

	/**
	 * @return
	 */
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

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

}
