package me.chyxion.tigon.webmvc;

import java.util.Map;
import java.util.HashMap;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.AfterReturning;

/**
 * process return map
 * @version 0.0.2
 * @since 0.0.1
 * @author Donghuang <br>
 * donghuang@wacai.com <br>
 * Jun 25, 2014 9:00:57 PM
 */
@Slf4j
@Aspect
public class TigonControllerAspect {

    /**
     * Class Within <code>@Controller</code>,
     * And Without <code>@ResponseBody</code>
     */
    @Pointcut("(@target(org.springframework.stereotype.Controller) || " + 
            "@within(org.springframework.stereotype.Controller)) && " + 
            "!@target(org.springframework.web.bind.annotation.ResponseBody) && " + 
            "!@within(org.springframework.web.bind.annotation.ResponseBody)")
    public void controllerBean() {}

    /**
     * Method Within <code>@RequestMapping</code>,
     * Returns Map,
     * Without <code>@ResponseBody</code>
     */
    @Pointcut("execution(@org.springframework.web.bind.annotation.RequestMapping public * *(..)) && " + 
            "!@annotation(org.springframework.web.bind.annotation.ResponseBody)")
    public void methodPointcut() {}

    @AfterReturning(pointcut = "controllerBean() && methodPointcut()", returning = "result")
    public void afterReturning(JoinPoint jp, Object result) {
        if (result instanceof Map) {
            if (log.isDebugEnabled()) {
                log.debug("Controller aspect after returning, return map [{}].", JSON.toJSON(result));
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> mapRtn = (Map<String, Object>) result;
            Map<String, Object> mapData = new HashMap<String, Object>(mapRtn);
            mapRtn.clear();
            mapRtn.put(JSONView.MAP_DATA, true);
            mapRtn.put(JSONView.DATA_KEY, mapData);
        }
    }
}
