package com.chushang.oss.consumer;

import com.chushang.common.core.constant.SecurityConstants;
import com.chushang.common.core.constant.ServiceConstant;
import com.chushang.common.core.context.SecurityContextHolder;
import com.chushang.common.core.util.SpringUtils;
import com.chushang.common.core.web.AjaxResult;
import com.chushang.common.core.web.Result;
import com.chushang.task.entity.TaskInfo;
import com.chushang.task.entity.dto.UpdateTaskDTO;
import com.chushang.task.enums.TaskStatusEnum;
import com.chushang.task.enums.TaskTypeEnum;
import com.chushang.task.feign.RemoteTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * @auther: zhao
 * @date: 2024/6/12 16:59
 */
@Slf4j
@Component
@RocketMQMessageListener(topic = ServiceConstant.OSS, consumerGroup = ServiceConstant.OSS_CONSUMER_GROUP)
public class OssConsumerService implements RocketMQListener<TaskInfo> {
    @Resource
    RemoteTaskService remoteTaskService;
    /**
     *  执行 下发的 后台任务
     */
    @Override
    public void onMessage(TaskInfo message) {
        remoteTaskService.updateTask(message.getTaskId(), UpdateTaskDTO.builder()
                .taskStatus(TaskStatusEnum.EXECUTING)
                .build(), SecurityConstants.INNER);
        // 通过 反射 去执行具体方法
        String className = message.getClassName();
        String methodName = message.getMethodName();
        String params = message.getParams();
        Integer taskType = message.getTaskType();
        SecurityContextHolder.setDeptId(message.getDeptId()+"");
        UpdateTaskDTO updateTask = new UpdateTaskDTO();
        try {
            // 包名+类名
            Class classzz = Class.forName(className);
            // 获取构造器对象
            // 利用spring 获取对象
            Object o = SpringUtils.getBean(classzz);
            // 传递需要执行的方法
            Method method = classzz.getMethod(methodName, String.class);
            // 调用的方法有多个参数  Method method = classzz.getMethod("class1method",long.class,String.class,String.class);
            // 如果调用的方法有参数 invoke(o,param1,param2,param3,...)
            updateTask.setLastRunTime(LocalDateTime.now());
            Object invoke = method.invoke(o, params);
            if (invoke instanceof AjaxResult result){
                Integer code = (Integer) result.get(AjaxResult.DATA_TAG);
                if (result.isSuccess() && 200 == code){
                    updateTask.setTaskStatus(TaskStatusEnum.EXECUTE_SUCCESS);
                    String data = (String)result.get(AjaxResult.DATA_TAG);
                    updateTask.setLastRunResult("success");
                    if (Objects.equals(taskType, TaskTypeEnum.DOWN.getCode())){
                        updateTask.setRemark(data);
                    }
                }else {
                    String errMsg = (String)result.get(AjaxResult.MSG_TAG);
                    updateTask.setTaskStatus(TaskStatusEnum.EXECUTE_FAIL);
                    updateTask.setLastRunResult(errMsg);
                }
            }else if (invoke instanceof Result<?> result){
                if (result.isSuccess() && result.getCode() == 200){
                    updateTask.setTaskStatus(TaskStatusEnum.EXECUTE_SUCCESS);
                    String data = (String)result.getData();
                    updateTask.setLastRunResult("success");
                    if (Objects.equals(taskType, TaskTypeEnum.DOWN.getCode())){
                        updateTask.setRemark(data);
                    }
                }else {
                    String errMsg = result.getMsg();
                    updateTask.setTaskStatus(TaskStatusEnum.EXECUTE_FAIL);
                    updateTask.setLastRunResult(errMsg);
                }
            }
        }catch (Exception e){
            log.error("执行失败", e);
            updateTask.setTaskStatus(TaskStatusEnum.EXECUTE_FAIL);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(e).append("\n");
            for (StackTraceElement s : e.getStackTrace()) {
                stringBuilder.append(s.toString()).append("\n");
            }
            updateTask.setLastRunResult(stringBuilder.toString());
        }
        // 执行完毕后 更新 任务状态
        remoteTaskService.updateTask(message.getTaskId(), updateTask, SecurityConstants.INNER);
    }
}
