package cn.reghao.devops.web.admin.sys.service;

import cn.reghao.devops.web.admin.sys.service.notifier.ding.DingMsg;
import cn.reghao.devops.web.admin.sys.service.notifier.ding.DingNotify;
import cn.reghao.devops.web.admin.sys.service.notifier.email.EmailMsg;
import cn.reghao.devops.web.admin.sys.service.notifier.email.EmailNotify;
import cn.reghao.devops.web.admin.sys.db.repository.NotifyReceiverRepository;
import cn.reghao.devops.web.admin.sys.model.vo.NotifyType;
import cn.reghao.devops.web.admin.sys.model.po.NotifyReceiver;
import cn.reghao.devops.web.admin.sys.service.notifier.Notify;
import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutorService;

/**
 * 通知服务
 *
 * @author reghao
 * @date 2021-02-25 00:10:17
 */
@Slf4j
@Service
public class NotifyService {
    private final ExecutorService threadPool = ThreadPoolWrapper.threadPool("notify-service");
    private final DingNotify dingNotify;
    private final EmailNotify emailNotify;
    private final NotifyReceiverRepository notifyReceiverRepository;
    private SysMessageService sysMessageService;

    public NotifyService(DingNotify dingNotify, EmailNotify emailNotify,
                         NotifyReceiverRepository notifyReceiverRepository, SysMessageService sysMessageService) {
        this.dingNotify = dingNotify;
        this.emailNotify = emailNotify;
        this.notifyReceiverRepository = notifyReceiverRepository;
        this.sysMessageService = sysMessageService;
    }

    public <T> void notify(T msg) {
        String receiver;
        if (msg instanceof DingMsg) {
            NotifyReceiver notifyReceiver = notifyReceiverRepository.findByType(NotifyType.webhook.getName());
            if (notifyReceiver != null) {
                receiver = notifyReceiver.getUrl();
                DingMsg dingMsg = (DingMsg) msg;
                threadPool.execute(new NotifyTask<>(sysMessageService, dingNotify, receiver, dingMsg));
            }
        } else if (msg instanceof EmailMsg) {
            NotifyReceiver notifyReceiver = notifyReceiverRepository.findByType(NotifyType.email.getName());
            if (notifyReceiver != null) {
                receiver = notifyReceiver.getUrl();
                EmailMsg emailMsg = (EmailMsg) msg;
                threadPool.execute(new NotifyTask<>(sysMessageService, emailNotify, receiver, emailMsg));
            }
        }
    }

    public <T> void notify(String receiver, T msg) {
        if (msg instanceof DingMsg) {
            DingMsg dingMsg = (DingMsg) msg;
            threadPool.execute(new NotifyTask<>(sysMessageService, dingNotify, receiver, dingMsg));
        } else if (msg instanceof EmailMsg) {
            EmailMsg emailMsg = (EmailMsg) msg;
            threadPool.execute(new NotifyTask<>(sysMessageService, emailNotify, receiver, emailMsg));
        }
    }
    /**
     * @param
     * @return
     * @date 2021-06-23 上午9:29
     */
    static class NotifyTask<T> implements Runnable {
        private SysMessageService sysMessageService;
        private final Notify<T> notify;
        private final String receiver;
        private final T msg;

        public NotifyTask(SysMessageService sysMessageService, Notify<T> notify, String receiver, T msg) {
            this.sysMessageService = sysMessageService;
            this.notify = notify;
            this.receiver = receiver;
            this.msg = msg;
        }

        @Override
        public void run() {
            try {
                notify.send(receiver, msg);
            } catch (Exception e) {
                String title = "发送通知失败";
                String content = String.format("发送给 %s 的通知失败 -> %s", receiver, e.getMessage());
                sysMessageService.putSysMessage(title, content);
            }
        }
    }
}
