package cn.ibizlab.r7.runtime.util.web;

import java.util.Iterator;
import java.util.Map;

import org.springframework.core.MethodParameter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import cn.ibizlab.r7.runtime.util.SearchContext;

public class SearchContextHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return SearchContext.class.isAssignableFrom(parameter.getParameterType());
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		SearchContext searchContext = (SearchContext)parameter.getParameterType().newInstance();
		fillSessionContext(searchContext, webRequest);
		Map<String, String[]> params = webRequest.getParameterMap();
		PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver();
		Pageable pageable = pageableResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory) ;
		searchContext.setPageable(pageable);
		for (String key : params.keySet()) {
			if(key.equalsIgnoreCase("page")||key.equalsIgnoreCase("size")||key.equalsIgnoreCase("sort"))
				continue ;
			if(key.equalsIgnoreCase("query")){
				searchContext.setQuery(params.get(key)[0]);
				continue ;
			}
			if(key.equalsIgnoreCase("customparams")){
				searchContext.setCustomParams(params.get(key)[0]);
				continue ;
			}
			if(key.equalsIgnoreCase("customcond")){
				searchContext.setCustomCond(params.get(key)[0]);
				continue ;
			}
			searchContext.set(key, params.get(key)[0]);
		}
		return searchContext;
	}

	private void fillSessionContext(SearchContext searchContext,NativeWebRequest webRequest) {
		Iterator<String> headers = webRequest.getHeaderNames() ;
		while(headers.hasNext()) {
			String headerName = headers.next() ;
			if(headerName.toUpperCase().startsWith(SessionConstants.SESSIONPREFIX)) {
				searchContext.getSessioncontext().put(headerName.toUpperCase().replace(SessionConstants.SESSIONPREFIX, ""), webRequest.getHeader(headerName)) ;
			}
		}
	}
}
