package cc.smtweb.framework.core.mvc.controller.binder.body;

import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.BindBeanException;
import cc.smtweb.framework.core.mvc.controller.IBeanContext;
import cc.smtweb.framework.core.mvc.controller.IEditor;
import cc.smtweb.framework.core.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;

/**
 * API函数@SwBody参数的转换处理，POST请求直接转换Json内容为Bean对象，GET请求转换Map请求参数为Bean对
 *
 * @author xkliu
 */
public class SwMapBodyEditor implements IEditor {
    @Override
    public Object getParamValue(String paramName, Class<?> paramType, IBeanContext context, Map<String, Object> params, String body, HttpServletRequest request) {
        Object map = request.getAttribute(BODY_MAP);
        if (map != null) {
            return getFieldValue((SwMap) map, paramName);
        }

        if (body != null) {
            return getPostValue(paramName, paramType, body, request);
        } else {
            return getGetValue(paramName, paramType, params, request);
        }
    }

    private Object getGetValue(String paramName, Class<?> paramType, Map<String, Object> params, HttpServletRequest request) {
        SwMap result = JsonUtil.parseSimple(params, SwMap.class);
        if(result!=null){
            SwMap header = getHeaderMap(request);
            result.put("_header",header);
        }
        request.setAttribute(BODY_MAP, result);
        return getFieldValue(result, paramName);
    }

    private Object getPostValue(String paramName, Class<?> paramType, String body, HttpServletRequest request) {
        if (body == null || StringUtils.isBlank(body)) {
            return null;
        }

        SwMap result = JsonUtil.parse(body, SwMap.class);
        if(result!=null){
            SwMap header = getHeaderMap(request);
            result.put("_header",header);
        }
        request.setAttribute(BODY_MAP, result);
        return getFieldValue(result, paramName);
    }
    private SwMap getHeaderMap( HttpServletRequest request){
        SwMap header = new SwMap();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (null != headerNames) {
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                String headerValue = request.getHeader(headerName);
                header.put(headerName,headerValue);
            }
        }
        return header;
    }
    private Object getFieldValue(SwMap result, String paramName) {
        if (paramName != null) {
            Object value = result.get(paramName);
            if (value == null) {
                return null;
            }

            if (value instanceof Map) {
                SwMap map = new SwMap();
                ((Map) value).forEach((k, v) -> {
                    map.put(k.toString(), v);
                });
                return map;
            }

            throw new BindBeanException("传入的 @SwBody(" + paramName + ") 值非MAP类型! " + value.getClass().getName());
        }

        return result;
    }

}
