package net.northking.cctp.upperComputer.webSocket.thread;

import net.northking.cctp.upperComputer.deviceManager.HarmonyDeviceManager;
import net.northking.cctp.upperComputer.deviceManager.thread.HarmonyProvider;
import net.northking.cctp.upperComputer.driver.harmony.ui.UiComponent;
import net.northking.cctp.upperComputer.utils.SessionUtils;
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.websocket.Session;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : yineng.huang
 * @date : 2024/4/25 16:22
 */
public class HarmonyGetNodeTreeThread extends Thread {

    private final Logger logger = LoggerFactory.getLogger(HarmonyGetNodeTreeThread.class);

    private Session session;

    private String deviceId;

    private CmdRequest request;

    private boolean keepPushNode = true;  //前端是否打开了获取ui节点

    private final Object lock = new Object();


    public HarmonyGetNodeTreeThread(Session session, String deviceId, CmdRequest request) {
        this.session = session;
        this.deviceId = deviceId;
        this.request = request;
        this.keepPushNode = true;
        setName(deviceId + "】node节点");
    }

    @Override
    public void run() {
        logger.info("开始获取设备【{}】的节点............................", deviceId);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        try {
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            logger.error("Document创建失败",e);
            return;
        }
        Map<String, String> data = new HashMap<>();
        while (!isInterrupted()) {
            if (keepPushNode) {
                try {
                    HarmonyProvider harmonyProvider = HarmonyDeviceManager.getInstance().getCurrentDeviceProvider(this.deviceId);
                    if (null == harmonyProvider) {
                        logger.debug("设备【{}】掉线了,等一下，不要急........................", deviceId);
                        break;
                    }
                    UiComponent uiComponent = harmonyProvider.captureLayout();
                    logger.debug("获取结束，nodeData空：{}", uiComponent == null);
                    if (null != uiComponent) {
                        Document document = builder.newDocument();
                        Node xmlElement = uiComponent.createXMLElement(document);
                        document.appendChild(xmlElement);
                        String xml = toXMLString(document);
                        data.put("data", xml);
                        SessionUtils.sendContinuousData(session, request, data, "获取节点树成功");
                    } else {
                        logger.debug("获取结束，nodeData为空，等会再重试");
                    }
                } catch (IllegalStateException e) {
                    logger.warn("webSession已经关闭",e);
                    break;
                } catch (Exception e) {
                    logger.warn("设备【{}】获取节点出了点问题，但是不影响，继续", deviceId, e);
                }
                synchronized (lock) {
                    logger.warn("设备【{}】等待下一次获取node节点.....................", deviceId);
                    try {
                        lock.wait(1*1000);
                    } catch (InterruptedException e) {
                        interrupt();
                        break;
                    }
                }
            } else {
                synchronized (lock) {
                    logger.warn("设备【{}】等待获取node节点.....................", deviceId);
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        interrupt();
                        break;
                    }
                }
            }
        }
        logger.info("设备【{}】获取node节点线程退出...............", deviceId);
    }

    public CmdRequest getRequest() {
        return request;
    }

    public void setRequest(CmdRequest request) {
        this.request = request;
    }


    public void stopGetNodeTree(CmdRequest request) {
        SessionUtils.sendSuccessData(session, this.request, null, "即将停止获取节点树........");
        SessionUtils.sendSuccessData(session, request, null, "停止获取节点树成功........");
        this.keepPushNode = false;
    }

    public void startGetNodeTree(CmdRequest request) {
        this.request = request;
        this.keepPushNode = true;
        synchronized (lock) {
            logger.debug("设备【{}】开始获取节点树...................", deviceId);
            lock.notify();
        }
    }


    public void exitGetNodeTree() {
        interrupt();
    }

    public void getOnceNodeTree() {
        if (keepPushNode) {
            synchronized (lock) {
                logger.debug("设备【{}】操作了，获取一次节点树...................", deviceId);
                lock.notify();
            }
        } else {
            logger.warn("设备【{}】前端已经关闭了uiNode，无需获取.............", deviceId);
        }
    }

    String toXMLString(Document document) throws TransformerException {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(new DOMSource(document), result);
        return writer.toString();
    }
}
