package com.bocloud.ims.service.thread;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.monitor.AlarmDriver;
import com.bocloud.cmp.entity.enums.AlarmLevel;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.AlarmModel;
import com.bocloud.common.enums.BoCloudExchange;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.OperateResult.OperateCategory;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ResourceAlarm;
import com.bocloud.ims.repository.resource.ResourceAlarmRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 告警同步任务类
 *
 * @author dmw
 */
public class AlarmSyncTask {
    private static Logger logger = LoggerFactory.getLogger(AlarmSyncTask.class);
    private Long userId;// 操作者ID
    private CloudVendor vendor; // 云平台
    private ResourceAlarmRepository alarmRepository;// 告警数据库操作接口
    private AlarmDriver alarmDriver;// 告警提供者
    private AmqpTemplate amqpTemplate;
    private static final String EXCHANGE = BoCloudExchange.Default.TOPIC.getExchange();
    private static final String PROGRESS_QUEUE = "bocloud.message.queue.#";

    public void execute() {
        // 启动一个线程
        new Thread(
                () -> {
                    try {
                        alarmRepository.deleteByVendor(vendor.getId());
                        BocloudResult result = alarmDriver.list(vendor.getUuid(), null);
                        if (null == result.getData()) {
                            return;
                        }
                        String content = JSONObject.toJSONString(result.getData());
                        List<AlarmModel> alarmModelList = JSONObject.parseArray(content, AlarmModel.class);
                        alarmModelList.stream().forEach(
                                alarmModel -> {
                                    if (null != alarmModel.getTarget()) {
                                        alarmModel.setTargetName(alarmModel.getTarget());
                                        alarmModel.setTarget(null);
                                    }
                                }
                        );

                        List<ResourceAlarm> newAlarms = JSONObject.parseArray(JSONObject.toJSONString(alarmModelList), ResourceAlarm.class);
                        if (ListTool.isEmpty(newAlarms)) {
                            return;
                        }
                        for (ResourceAlarm alarm : newAlarms) {
                            alarm.setMenderId(userId);
                            alarm.setCreatorId(userId);
                            alarm.setVendorId(vendor.getId());
                            alarm.setName(null == alarm.getName() ? null : alarm.getName().replace("'", "-"));
                            alarm.setDealResult(null == alarm.getDealResult() ? null : alarm.getDealResult().replace(
                                    "'", "-"));
                            alarm.setProps(null == alarm.getProps() ? null : alarm.getProps().replace("'", "-"));
                            alarm.setRemark(null == alarm.getRemark() ? null : alarm.getRemark().replace("'", "-"));
                            if (null == alarm.getConfirmer()) {
                                alarm.setStatus(BocloudStatus.Alarm.UNCONFIRMED.name());
                            } else {
                                alarm.setStatus(BocloudStatus.Alarm.CONFIRMED.name());
                            }
                            if (CloudProvider.VMWARE.name().equals(vendor.getType())) {
                                if ("red".equals(alarm.getLevel())) {
                                    alarm.setLevel(AlarmLevel.DANGER.name());
                                } else {
                                    alarm.setLevel(AlarmLevel.WARN.name());
                                }
                            }
                        }
                        alarmRepository.batchSave(newAlarms, 1000);
                        sendWebSocketMessage(vendor.getName());
                    } catch (Exception e) {
                        logger.error("Sync cloudvendor 【{}】 alarm error !", vendor.getName(), e);
                    }
                }).start();
    }

    public AlarmSyncTask(Long userId, CloudVendor vendor, ResourceAlarmRepository alarmRepository,
                         AlarmDriver alarmDriver, AmqpTemplate amqpTemplate) {
        super();
        this.userId = userId;
        this.vendor = vendor;
        this.alarmRepository = alarmRepository;
        this.alarmDriver = alarmDriver;
        this.amqpTemplate = amqpTemplate;
    }

    /**
     * 发消息给前台
     *
     * @param vendor
     */
    private void sendWebSocketMessage(String vendor) {
        // 进度消息处理
        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("vendor", vendor);

        OperateResult operateResult = new OperateResult();
        operateResult.setOperate("alarm");
        operateResult.setCategory(OperateCategory.ProviderAlarm);
        operateResult.setSuccess(true);
        operateResult.setData(messageMap);
        // 将执行结果写入mq 由web写入websock给前端
        amqpTemplate.convertAndSend(EXCHANGE, PROGRESS_QUEUE, operateResult);
    }

    /**
     * @return the userId
     */
    public Long getUserId() {
        return userId;
    }

    /**
     * @param userId the userId to set
     */
    public void setUserId(Long userId) {
        this.userId = userId;
    }

    /**
     * @return the vendor
     */
    public CloudVendor getVendor() {
        return vendor;
    }

    /**
     * @param vendor the vendor to set
     */
    public void setVendor(CloudVendor vendor) {
        this.vendor = vendor;
    }

    /**
     * @return the alarmRepository
     */
    public ResourceAlarmRepository getAlarmRepository() {
        return alarmRepository;
    }

    /**
     * @param alarmRepository the alarmRepository to set
     */
    public void setAlarmRepository(ResourceAlarmRepository alarmRepository) {
        this.alarmRepository = alarmRepository;
    }

    /**
     * @return the alarmDriver
     */
    public AlarmDriver getAlarmDriver() {
        return alarmDriver;
    }

    /**
     * @param alarmDriver the alarmDriver to set
     */
    public void setAlarmDriver(AlarmDriver alarmDriver) {
        this.alarmDriver = alarmDriver;
    }

}
