package org.jeecg.pm.mq;


import com.chanjx.utils.StringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.pm.entity.EventDis;
import org.jeecg.pm.entity.PmEventInfo;
import org.jeecg.pm.entity.enums.EventLevel;
import org.jeecg.pm.entity.enums.EventState;
import org.jeecg.pm.service.IPmEventInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.jms.BytesMessage;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;

/**
 * @author: JJww
 * @Date:2022/3/23
 */
@Slf4j
@Component
public class EventMessageListener {

    /**
     * 视频事件
     */
    private final static String VSS_TOPIC = "openapi.vss.topic";

    /**
     * 报警事件
     */
    private final static String EPS_TOPIC = "openapi.eps.topic";

    @Autowired
    private IPmEventInfoService pmEventInfoService;


    @Autowired
    private RedisTemplate redisTemplate;

    @JmsListener(destination = VSS_TOPIC)
    public void vssProcessMessage(BytesMessage bytesMessage) throws Exception {
        String lock = VSS_TOPIC;
        try {
            final byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
            bytesMessage.readBytes(bytes);
            // 壳文件字段，EventDis类为event_dis.proto文件解析而来，CommEventLog类为事件壳文件类
            final EventDis.CommEventLog commEventLog = EventDis.CommEventLog.parseFrom(bytes);
            lock = lock + commEventLog.getLogId();
            if (redisTemplate.opsForValue().setIfAbsent(lock, lock)) {
                final PmEventInfo pmEventInfo = this.recode(commEventLog);
                pmEventInfo.setSubsystem(PmEventInfo.VSS);
                pmEventInfoService.saveEvent(pmEventInfo);
                log.info("VSS_TOPIC:{}", pmEventInfo);
            }
        } finally {
            redisTemplate.delete(lock);
        }
    }


    @JmsListener(destination = EPS_TOPIC)
    public void epsProcessMessage(BytesMessage bytesMessage) throws Exception {
        String lock = EPS_TOPIC;
        try {
            final byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
            bytesMessage.readBytes(bytes);
            // 壳文件字段，EventDis类为event_dis.proto文件解析而来，CommEventLog类为事件壳文件类
            final EventDis.CommEventLog commEventLog = EventDis.CommEventLog.parseFrom(bytes);
            lock = lock + commEventLog.getLogId();
            if (redisTemplate.opsForValue().setIfAbsent(lock, lock)) {
                final PmEventInfo pmEventInfo = this.recode(commEventLog);
                pmEventInfo.setSubsystem(PmEventInfo.EPS);
                pmEventInfoService.saveEvent(pmEventInfo);
                log.info("EPS_TOPIC:{}", pmEventInfo);
            }
        } finally {
            redisTemplate.delete(lock);
        }
    }


    @SneakyThrows
    public PmEventInfo recode(EventDis.CommEventLog commEventLog) {
        final EventLevel eventLevel = Arrays.asList(EventLevel.values()).stream().filter(level -> level.getLevel().equals(commEventLog.getEventLevel())).findFirst().orElse(EventLevel.UNKNOWN);
        final EventState eventState = Arrays.asList(EventState.values()).stream().filter(state -> state.getState().equals(commEventLog.getEventState())).findFirst().orElse(EventState.UNKNOWN);
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return new PmEventInfo()
                .setLogId(commEventLog.getLogId())
                .setEventState(eventState.getRemark())
                .setEventLevel(eventLevel.getRemark())
                .setUnitIdx(commEventLog.getUnitIdx())
                .setEventType(commEventLog.getEventType())
                .setEventTypeName(commEventLog.getEventTypeName())
                .setSubSysType(commEventLog.getSubSysType())
                .setEventName(commEventLog.getEventName())
                .setCreateTime(fmt.parse(commEventLog.getStartTime()))
                .setStopTime(StringUtils.isBlank(commEventLog.getStopTime()) ? null : fmt.parse(commEventLog.getStopTime()))
                .setSourceIdx(commEventLog.getSourceIdx())
                .setSourceType(commEventLog.getSourceType())
                .setSourceName(commEventLog.getSourceName())
                .setLogTxt(commEventLog.getLogTxt())
                .setRegionIdx(commEventLog.getRegionIdx())
                .setExtInfo(commEventLog.getExtInfo().toStringUtf8());
    }
}
