"""
GTKIPCListener — Cloud Hub Connection Handler
=============================================
Connects OUTBOUND to Noctua Cloud Hub via TCP.
Sends handshake to receive telemetry stream based on License Key.
"""

import threading
import socket
import ssl
import json
import os
import time
from gi.repository import GLib

class GTKIPCListener:
    def __init__(self, cfg: dict, on_event_callback, on_connect_callback=None,
                 on_disconnect_callback=None):
        self.cfg                = cfg
        self.on_event           = on_event_callback
        self.on_connect         = on_connect_callback
        self.on_disconnect      = on_disconnect_callback
        self._thread            = None
        self._running           = False
        self._sock              = None
        self.license_key        = self.cfg.get("license_key", "")
        self.connection_label   = f"TCP {self.cfg.get('server_host', '127.0.0.1')}:{self.cfg.get('server_port', 7443)}"

    def start(self):
        self._running = True
        self._thread  = threading.Thread(target=self._listen_loop, daemon=True)
        self._thread.start()

    def stop(self):
        self._running = False
        if self._sock:
            try:
                self._sock.close()
            except Exception:
                pass

    def _listen_loop(self):
        backoff = 0.5
        while self._running:
            try:
                host = self.cfg.get("server_host", "127.0.0.1")
                port = int(self.cfg.get("server_port", 7443))

                raw_sock = socket.create_connection((host, port), timeout=10)
                self._sock = raw_sock
                backoff = 0.5

                # Send Handshake
                handshake = json.dumps({"type": "DASHBOARD", "license_key": self.license_key}) + "\n"
                self._sock.sendall(handshake.encode('utf-8'))

                if self.on_connect:
                    GLib.idle_add(self.on_connect)

                # Read lines
                f = self._sock.makefile('r', encoding='utf-8')
                while self._running:
                    line = f.readline()
                    if not line:
                        break
                    
                    try:
                        event = json.loads(line)
                        if "error" in event:
                            GLib.idle_add(self._emit_error, event["error"])
                            break
                        GLib.idle_add(self.on_event, event)
                    except json.JSONDecodeError:
                        pass

            except (ConnectionRefusedError, FileNotFoundError, OSError):
                pass
            except Exception as e:
                GLib.idle_add(self._emit_error, str(e))
            finally:
                if self._sock:
                    try:
                        self._sock.close()
                    except Exception:
                        pass
                    self._sock = None
                if self.on_disconnect:
                    GLib.idle_add(self.on_disconnect)

            if self._running:
                time.sleep(backoff)
                backoff = min(backoff * 2, 30)

    def _emit_error(self, msg: str):
        self.on_event({
            "type": "system_error",
            "message": f"Connection failed: {msg}",
            "hint": "Check Cloud Hub and license key."
        })
