package com.nokia.tsl_data.scheduling.entity;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;

import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import com.nokia.tsl_data.config.SpringContextHolder;

import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Data
@Accessors(chain = true)
public class RunnableTask implements Runnable {

    private String taskId = "";
    private String beanName;
    private String methodName;
    private String methodParameter = "";
    private Long delay = 0L;

    @Override
    public void run() {
        try {
            Object bean = SpringContextHolder.getBean(beanName);
            Method method;
            if (StringUtils.hasLength(methodParameter)) {
                method = bean.getClass().getMethod(methodName, String.class);
                ReflectionUtils.makeAccessible(method);
                method.invoke(bean, methodParameter);
            } else {
                method = bean.getClass().getMethod(methodName);
                ReflectionUtils.makeAccessible(method);
                method.invoke(bean);
            }
        } catch (NoSuchMethodException e) {
            log.error("未找到方法: {}.{}()", beanName, methodName);
            e.printStackTrace();
        } catch (SecurityException e) {
            log.error("{}.{}() 方法报错 SecurityException", beanName, methodName);
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            log.error("{}.{}() 方法不允许访问", beanName, methodName);
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            log.error("{}.{}() 方法参数错误", beanName, methodName);
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            log.error("{}.{}() 方法执行出错：{}", beanName, methodName, e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof RunnableTask))
            return false;
        RunnableTask t = (RunnableTask) o;
        return taskId.equals(t.getTaskId())
                && beanName.equals(t.getBeanName())
                && methodName.equals(t.getMethodName())
                && methodParameter.equals(t.getMethodParameter())
                && delay.equals(t.getDelay());
    }

    @Override
    public int hashCode() {
        return Objects.hash(taskId, beanName, methodName, methodParameter, delay);
    }
}
