package io.wdd.rpc.message.sender;


import com.fasterxml.jackson.core.JsonProcessingException;
import io.wdd.common.handler.MyRuntimeException;
import io.wdd.rpc.init.InitRabbitMQConfig;
import io.wdd.rpc.message.OctopusMessage;
import io.wdd.rpc.message.OctopusMessageType;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

import static io.wdd.common.config.OctopusObjectMapperConfig.OctopusObjectMapper;

/**
 * adaptor
 * provide override method to convert Object and send to rabbitmq
 */
@Component
@Slf4j(topic = "Send Message To Octopus Agent ")
public class OMessageToAgentSender {

    @Resource
    RabbitTemplate rabbitTemplate;

    @Resource
    InitRabbitMQConfig initRabbitMQConfig;


    /**
     * send to Queue -- InitFromServer
     *
     * @param octopusMessage octopus octopusMessage
     */
    public void sendINIT(OctopusMessage octopusMessage) {

        // only accept INIT type octopusMessage
        if (!OctopusMessageType.INIT.equals(octopusMessage.getOctopusMessageType())) {
            throw new MyRuntimeException("To Agent Order method usage wrong !");
        }

        // send to Queue -- InitFromServer
        log.info(
                "send INIT OrderCommand to Agent = {}",
                octopusMessage
        );

        rabbitTemplate.convertAndSend(
                initRabbitMQConfig.INIT_EXCHANGE,
                initRabbitMQConfig.INIT_FROM_SERVER_KEY,
                writeData(octopusMessage)
        );

    }


    public void send(OctopusMessage octopusMessage) {

        log.debug(
                "OctopusMessage {} send to agent {}",
                octopusMessage,
                octopusMessage.getUuid()
        );

        // 统一处理Content
        if (!(octopusMessage.getContent() instanceof String)) {
            try {

                String contendString = OctopusObjectMapper.writeValueAsString(octopusMessage.getContent());

                octopusMessage.setContent(contendString);

            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }

        rabbitTemplate.convertAndSend(
                initRabbitMQConfig.OCTOPUS_EXCHANGE,
                octopusMessage.getUuid() + "*",
                writeData(octopusMessage)
        );

    }


    public void send(List<OctopusMessage> octopusMessageList) {

        octopusMessageList
                .stream()
                .forEach(
                        octopusMessage -> {
                            this.send(octopusMessage);
                        }
                );

    }

    @SneakyThrows
    private byte[] writeData(Object data) {

        return OctopusObjectMapper.writeValueAsBytes(data);
    }

}
