package com.yfyy.iotx;

import com.aliyun.iot.as.bridge.core.BridgeBootstrap;
import com.aliyun.iot.as.bridge.core.handler.DownlinkChannelHandler;
import com.aliyun.iot.as.bridge.core.handler.tsl.TslUplinkHandler;
import com.aliyun.iot.as.bridge.core.model.Session;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

// 网桥服务demo
public class BridgeTsl {
    private static Logger log = LoggerFactory.getLogger(BridgeTsl.class);
    private static BridgeBootstrap bridgeBootstrap;

    private static ExecutorService executorService = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() * 2,
            60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1000),
            new ThreadFactoryBuilder().setDaemon(true).setNameFormat("bridge-downlink-handle-%d").build(),
            new ThreadPoolExecutor.AbortPolicy());

    private final static Random random = new Random();

    public static void start() {
        // Use application.conf & devices.conf by default
        bridgeBootstrap = new BridgeBootstrap();
        bridgeBootstrap.bootstrap(new DownlinkChannelHandler() {
            @Override
            public boolean pushToDevice(Session session, String topic, byte[] payload) {
                // 获取到云端数据
                // 从云端获取下发数据
                executorService.submit(() -> handleDownLinkMessage(session, topic, payload));
                return true;
            }

            @Override
            public boolean broadcast(String s, byte[] bytes) {
                return false;
            }
        });
        log.info("======== Bridge bootstrap success =========");

        // original device identity, defined in devices.conf
//        String originalIdentity = "16082926";
//        onlineAndReportProperty(originalIdentity);
//        String demoDevice2 = "16082928";
//        onlineAndReportProperty(demoDevice2);
    }

    // 上线+上报属性
    private static void onlineAndReportProperty(String originalIdentity){
        // device Session of your specific protocol, If none, you can just use empty object
        Object originalChannel = new Object();
        Session session = Session.newInstance(originalIdentity, originalChannel);
        // 设备上线
        TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
        tslUplinkHandler.doOnline(session, originalIdentity);
        // 上报属性
        String requestId = String.valueOf(random.nextInt(1000));
        tslUplinkHandler.reportProperty(requestId, originalIdentity, "soilPH", 6.0d);
        tslUplinkHandler.reportProperty(requestId, originalIdentity, "soilHumidity", 31.2d);
        tslUplinkHandler.reportProperty(requestId, originalIdentity, "soilTemperature", 25d);
    }

    // 处理下发数据，本项目暂不处理
    private static void handleDownLinkMessage(Session session, String topic, byte[] payload) {
        String content = new String(payload);
        log.info("Get DownLink message, session:{}, topic:{}, content:{}", session, topic, content);
        Object channel = session.getChannel();
        String originalIdentity = session.getOriginalIdentity();
        //for example, you can send the message to device via channel, it depends on you specific server implementation
    }
}
