package com.apobates.forum.thrones.controller.helper;

import com.apobates.forum.member.entity.MemberOnline;
import com.apobates.forum.member.service.MemberOnlineService;
import com.apobates.forum.member.storage.OnlineMemberStorage;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.member.storage.core.MemberSessionBeanBuilder;
import com.apobates.forum.utils.Commons;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 在线会员记录拦截器
 * 
 * @author xiaofanku
 * @since 20200608
 */
@Aspect
public class OnlineDescriptorAspect {
    @Autowired
    private OnlineMemberStorage onlineMemberStorage;
    @Autowired
    private MemberOnlineService memberOnlineService;
    //时间缓冲剂
    private final static MemberOnlineCreationCache mocc = MemberOnlineCreationCache.getSingleton();
    private final static Logger logger = LoggerFactory.getLogger(OnlineDescriptorAspect.class);

    @Before("@annotation(descriptor)")
    public void doPermissionCheck(JoinPoint joinPoint, OnlineDescriptor descriptor) {
        CodeSignature signature = (CodeSignature) joinPoint.getStaticPart().getSignature();
        HttpServletRequest request = getHttpRequestParameter(joinPoint.getArgs(), signature.getParameterNames());
        if(null == request){
            logger.info("[ODA]no request parameter");
            return;
        }
        
        MemberSessionBean mbean = getMemberBean(request);
        MemberOnline mo = new MemberOnline(request.getSession().getId(), mbean.getMid(), mbean.getNames(), mbean.getNickname(), descriptor.action());
        // 不一定非要有一个存一个,N分钟内更新一次即可
        if(mocc.put(mo)){
            memberOnlineService.create(mo);
        }
    }
    
    private MemberSessionBean getMemberBean(HttpServletRequest request){
        MemberSessionBean mbean = onlineMemberStorage.getInstance(request, "OnlineDescriptorAspect").orElse(null);
        if (null == mbean || !mbean.isOnline()) {
            String ipAddr = Commons.getRequestIp(request);
            String gnick = String.format("Guest#%d", Commons.ipHashcode(ipAddr));
            mbean = MemberSessionBeanBuilder.empty().setNickname(gnick).build(Commons.getRequestIp(request), "ODA");
        }
        return mbean;
    }
    //获取注解方法中的HttpServletRequest参数
    private HttpServletRequest getHttpRequestParameter(Object[] paramValues, String[] paramNames) {
        HttpServletRequest req = null;
        for (int i = 0; i < paramValues.length; i++) {
            if (paramValues[i] instanceof HttpServletRequest) {
                try {
                    req = (HttpServletRequest) paramValues[i];
                    break;
                } catch (ClassCastException e) {
                    logger.info("[ODA]get request parameter, err: " + e.getMessage());
                }
            }
        }
        return req;
    }
}