package com.docus.server.collect.web.process;

import com.docus.core.util.Func;
import com.docus.core.util.SpringUtils;
import com.docus.core.util.json.JSON;
import com.docus.log.context.TrackContext;
import com.docus.log.processor.AbstractProcessor;
import com.docus.server.archivefile.service.ITaskMessageService;
import com.docus.server.collect.IConverter;
import com.docus.server.collect.IResult;
import com.docus.server.enums.CollectTypeEnum;
import com.docus.server.enums.StateEnum;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * @author linruifeng
 */
@Slf4j
public class VisitorProcessor extends AbstractProcessor {
    private ITaskMessageService messageService;
    private IConverter converter;
    private IResult result;

    /**
     * 前置通知
     */
    @Override
    public Object beforeProcess(TrackContext context) {
        super.beforeProcess(context);
        initBeans(context.getBeanNames());
        String message = (String) context.getArgs()[0];
        String retryKey = context.getRetryKey();
        if (Func.isEmpty(message)) {
            throw new RuntimeException("参数为空");
        }
        Long taskId = messageService.insertTaskMessage("", message, CollectTypeEnum.fromDesc(context.getGroup()), retryKey);
        String jsonStr = JSON.toJSON(converter.convert(message, context.getGroup()));
        messageService.updateTaskMessage(taskId, jsonStr, context.getExMessageResult(), StateEnum.OK);
        Map<String, Object> params = context.getParams();
        params.put("taskId", taskId);
        params.put("jsonStr", jsonStr);
        params.put("group", context.getGroup());
        return null;
    }

    /**
     * 后置和异常通知
     */
    @Override
    public Object doProcess(TrackContext context) {
        Map<String, Object> params = context.getParams();
        try {
            Long taskId = (Long) params.get("taskId");
            String afterReturnResult = (String) params.get("jsonStr");
            params.put("msg", context.getExMessageResult());

            if (Func.isNotEmpty(afterReturnResult)) {
                params.putAll(JSON.fromJSONWithGeneric(afterReturnResult, new TypeReference<Map<? extends String, ?>>() {
                }));
            }

            if (!context.isError()) {
                log.info("=== AOP 后置通知 ===");
                params.put("msg", "操作成功！");
                return result.ok(params);
            } else {
                log.info("=== AOP 异常通知 ===");
                log.error((String) params.get("msg"));
                messageService.updateTaskMessage(taskId, afterReturnResult, context.getExMessageResult(), StateEnum.FAIL);
                return result.fail(params);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return result.fail(params);
        }
    }

    /**
     * 初始化bean
     */
    public void initBeans(String[] beanNames) {
        this.converter = (IConverter) SpringUtils.getBean(beanNames[0]);
        this.result = (IResult) SpringUtils.getBean(beanNames[1]);
        this.messageService = SpringUtils.getBean(ITaskMessageService.class);
    }
}
