package net.northking.cctp.upperComputer.driver.harmony.hdc;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * HDC设备监控，用于监听HDC设备的变化
 * <br>
 * 每0.5秒查询一次（遵循DevEco Studio的行为）
 */

public class HDCDeviceObserver implements Runnable {
    private final Logger log = LoggerFactory.getLogger(HDCDeviceObserver.class);
    private final Thread thread = new Thread(this);
    private HDCSession hdcSession = null;
    private ArrayList<HDCDevice> lastDevices = new ArrayList<>();
    private final ArrayList<HDCDeviceListener> listeners = new ArrayList<>();

    HDCDeviceObserver() {
        thread.setName("HDCDeviceObserver");
    }

    /**
     * 开始进行HDC设备变动观察
     */
    public void start() {
        if (thread.isInterrupted()) throw new IllegalStateException("不能重新启动已经停止的设备监控");
        thread.start();
    }

    /**
     * 关闭当前正在进行的HDC设备变动观察
     */
    public void stop() {
        if (hdcSession != null) {
            hdcSession.close();
        }
        if (!thread.isInterrupted()) {
            thread.interrupt();
        }
        synchronized (listeners) {
            listeners.clear();
        }
    }

    /**
     * 添加设备变动监听器，当有HDC设备变化时触发
     *
     * @param listener 监听器
     */
    public void addHDCDeviceListener(HDCDeviceListener listener) {
        synchronized (listeners) {
            listeners.add(listener);
        }
    }

    /**
     * 移除HDC设备变动监听器
     *
     * @param listener 监听器
     */
    public void removeHDCDeviceListener(HDCDeviceListener listener) {
        synchronized (listeners) {
            listeners.remove(listener);
        }
    }

    @Override
    public void run() {
        while (!thread.isInterrupted()) {
            if (hdcSession == null) {
                hdcSession = Hdc.getInstance().createSession();
                if (hdcSession == null) {
                    log.warn("无法创建HDC会话，等待5秒重试");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        break;
                    }
                    continue;
                }
                try {
                    hdcSession.sendHdcData("alive\0".getBytes(StandardCharsets.UTF_8));
                } catch (IOException e) {
                    log.error("观察HDC设备变化发送长连接指令时发生IO错误", e);
                    hdcSession = null;
                    continue;
                }
            }

            ArrayList<HDCDevice> devices = Hdc.getInstance().listTargets(hdcSession);
            if (devices == null) {
                log.warn("监控设备动态失败：无法与HDC进行通信，等待10秒……");
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    break;
                }
                continue;
            }
            boolean hasDifferent = devices.size() != lastDevices.size();
            if (!hasDifferent) {
                for (int i = 0; i < devices.size(); i++) {
                    if (!devices.get(i).equals(lastDevices.get(i))) {
                        hasDifferent = true;
                        break;
                    }
                }
            }
            if (hasDifferent) {
                synchronized (listeners) {
                    try {
                        for (HDCDeviceListener l : listeners) {
                            l.onDeviceChanged(devices);
                        }
                    } catch (Exception e) {
                        log.error("设备变动监听器发生异常", e);
                    }
                }
            }
            lastDevices = devices;

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                break;
            }
        }
        log.warn("harmony设备监听退出................................");
    }
}
