package com.sptg.device.api;

import com.rabbitmq.client.*;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.constant.HttpConstant;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.entity.MqConf;
import com.sptg.device.api.util.RabbitMqConnectionUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * title: DeviceClientTest
 * package: com.sptg.device.api
 * description: 设备客户端测试用例
 *
 *
 *
 */
@Slf4j
@SuppressWarnings(value = "all")
public class DeviceClientTest {

    private static final RestTemplate restTemplate = new RestTemplate();

    @Setter
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    private static class QueueInfo {
        //  交换机名称
        private String exchangeName;
        //  交换机类型
        private String exchangeType;
        //  队列名称前缀
        private String queuePrefix;
        //  队列参数
        private Map<String,Object> queueParameter;
        //  持久化
        private Boolean durable;
        //  自动删除
        private Boolean autoDelete;
    }

    //  队列信息列表
    private static final List<QueueInfo> QUEUE_INFO_LIST = new ArrayList<>();

    static {
        Map<String,Object> map = new HashMap<>();
        map.put("x-message-ttl", 1000 * 60 * 5);
        //  临时交换机和队列
        QUEUE_INFO_LIST.add(new QueueInfo("TRANSIENT_EXCHANGE","direct","transient_",map,true,false));
        //  持久交换机和队列
        QUEUE_INFO_LIST.add(new QueueInfo("PERSISTENT_EXCHANGE","direct","persistent_",null,true,false));

    }

    private static final long TIME = 1000 * 60 * 30;

    //  设备序列号列表
    private static final List<String> serialNumberList = new ArrayList<>(Arrays.asList(
            "41-1"
    ));

    private static final String SERVER_ADDRESS = "http://smart.lezhuapp.com:19081";

    //  创建队列
    private static void createQueue(String serialNumber,QueueInfo queueInfo,Channel channel)throws IOException {
        //  声明队列
        String queueName = queueInfo.getQueuePrefix() + serialNumber;
        channel.queueDeclare(queueName,queueInfo.getDurable(),false,queueInfo.getAutoDelete(),queueInfo.getQueueParameter());
        //  声明交换机
        channel.exchangeDeclare(queueInfo.getExchangeName(), queueInfo.getExchangeType());
        //  绑定交换机
        channel.queueBind(queueName, queueInfo.getExchangeName(), serialNumber);
        channel.queueBind(queueName, queueInfo.getExchangeName(), "");
        //  消费者对象
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body){
                String message = new String(body, StandardCharsets.UTF_8);
                System.err.println("----------- [" + queueInfo.getExchangeName() + "] -----------");
                System.err.println("serialNumber:" + serialNumber);
                System.err.println("message:" + message);
                System.err.println("nowTime:" + System.currentTimeMillis() + "\n");
            }
        };
        //  接收消息并自动确认消息
        channel.basicConsume(queueName,true,consumer);
    }

    private static Device getDeviceByNumber(String serialNumber){
        //  接口地址
        String url = SERVER_ADDRESS + "/device/status/start";

        Device device = new Device();
        device.setSerialNumber(serialNumber);
        device.setDeviceFactory("qst");
        device.setDeviceModelNumber("21ch");
        device.setVersionNumber("1");
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpConstant.DATA_SIGN, DigestUtils.md5Hex(JsonUtils.objectToJson(device)));
        headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
        headers.add("Content-Type",HttpConstant.APPLICATION_JSON_UTF8);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(device), headers);
        String result = restTemplate.postForObject(url, requestEntity, String.class);

        ResultBean resultBean = JsonUtils.jsonToPojo(result, ResultBean.class);
        if (null == resultBean) {
            return null;
        }
        String json = JsonUtils.objectToJson(resultBean.getData());
        System.err.println(json);
        return JsonUtils.jsonToPojo(json,Device.class);
    }

    public static void main(String[] args){

        serialNumberList.forEach(serialNumber -> {
            //  获取设备信息
            Device device = getDeviceByNumber(serialNumber);
            if (null != device) {
                //  获取队列信息
                MqConf mqConf = device.getMqConf();
                try {
                    //  获取链接
                    Connection connection = RabbitMqConnectionUtil.openConnection(mqConf);
                    //  创建管道
                    Channel channel = connection.createChannel();
                    //  创建队列
                    QUEUE_INFO_LIST.forEach(queueInfo -> {
                        try{
                            createQueue(serialNumber,queueInfo,channel);
                        }catch (IOException e){
                            log.error(e.getMessage(),e);
                        }
                    });

                    //  创建定时器 (设备心跳检查)
                    Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            String url = SERVER_ADDRESS + "/device/check/heartbeat";
                            HttpHeaders headers = new HttpHeaders();
                            headers.add(HttpConstant.DATA_SIGN, DigestUtils.md5Hex(serialNumber));
                            headers.add("Accept", MediaType.APPLICATION_JSON_UTF8.toString());
                            headers.add("Content-Type",HttpConstant.APPLICATION_JSON);
                            HttpEntity<String> requestEntity = new HttpEntity<>(serialNumber, headers);
                            restTemplate.postForObject(url, requestEntity, String.class);
                        }
                    }, 0, TIME);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }else {
                log.warn("没有找到设备");
            }
        });
    }

}
