package com.mortals.xhx.module.device.service.impl;

import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.xhx.base.system.message.MessageService;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.device.dao.DeviceDao;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.platform.model.PlatformEntity;
import com.mortals.xhx.module.platform.service.PlatformService;
import com.mortals.xhx.module.product.model.ProductEntity;
import com.mortals.xhx.module.product.service.ProductService;
import com.mortals.xhx.queue.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * DeviceService
 * 设备 service实现
 *
 * @author zxfei
 * @date 2022-03-09
 */
@Service("deviceService")
@Slf4j
public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, DeviceEntity, Long> implements DeviceService {

    @Autowired
    private ProductService productService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private DefaultTbCoreConsumerService consumerService;

    @Override
    protected String getExtKey(DeviceEntity data) {
        return data.getDeviceCode();
    }

    @Autowired
    private MessageService messageService;

    @Override
    public ApiResp<String> sendDeviceMessage(DeviceEntity deviceEntity, TopicPartitionInfo info, TbQueueMsgHeaders header, String message, Context context) {
        ApiResp<String> resp = new ApiResp<>();
        resp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        resp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        TbQueueCallback callback = new TbQueueCallback() {
            @Override
            public void onSuccess(TbQueueMsgMetadata metadata) {
                log.info("消息投递成功,设备通道编码:" + deviceEntity.getDeviceMac());
            }

            @Override
            public void onFailure(Throwable t) {
                log.error("消息投递成功,设备通道编码:" + deviceEntity.getDeviceMac(), t);

            }
        };
        messageService.send(info, header, message, callback);
        return resp;
    }

    @Override
    public ApiResp<String> sendDeviceMessage(List<Long> deviceIds, TopicPartitionInfo info, TbQueueMsgHeaders header, String message, Context context) {
        ApiResp<String> resp = new ApiResp<>();
        DeviceQuery deviceQuery = new DeviceQuery();
        deviceQuery.setIdList(deviceIds);
        List<DeviceEntity> deviceEntityList = this.find(deviceQuery);
        for (DeviceEntity deviceEntity : deviceEntityList) {
            resp = sendDeviceMessage(deviceEntity, info, header, message, context);
        }
        return resp;
    }


    @Override
    protected void saveAfter(DeviceEntity entity, Context context) throws AppException {

        PlatformEntity platformEntity = platformService.get(entity.getPlatformId());
        ProductEntity productEntity = productService.get(entity.getProductId());
        if (!ObjectUtils.isEmpty(platformEntity) && ObjectUtils.isEmpty(productEntity)) {
            //注册rabbmit相关队列与绑定
            String exchangeName = platformEntity.getPlatformSn() + Constant.EXCHANGE_SPLIT + productEntity.getProductCode();
            TopicPartitionInfo info = TopicPartitionInfo.builder().exchangeName(exchangeName).topic(Constant.UPLOAD_TOPIC + entity.getDeviceCode()).build();
            TbQueueCallback callback = new TbQueueCallback() {
                @Override
                public void onSuccess(TbQueueMsgMetadata metadata) {
                    log.info("队列创建成功,设备编码:{}", entity.getDeviceCode());
                }

                @Override
                public void onFailure(Throwable t) {
                    log.error("队列创建失败,设备通道编码:{},{}", entity.getDeviceCode(), t);

                }
            };
            messageService.queueDeclare(info, callback);
            //消费监听线程添加当前声明队列
            Set<TopicPartitionInfo> partitions = new HashSet<>();
            partitions.add(info);
            consumerService.getMainConsumer().subscribe(partitions);
        }


        super.saveAfter(entity, context);
    }
}