from __future__ import annotations
import logging
import threading
import socket
import time
from queue import Queue, Full, Empty


class TelnetHandler(logging.Handler):
    """
    Asynchronous logging handler that writes to a TCP/Telnet client.
    """

    def __init__(
        self,
        host: str = "127.0.0.1",
        port: int = 5000,
        encoding: str = "utf-8",
        newline: str = "\r\n",
        queue_maxsize: int = 1000,
        daemon_thread: bool = True,
    ):
        super().__init__()
        self.host = host
        self.port = port
        self.encoding = encoding
        self.newline = newline
        self.queue = Queue(maxsize=queue_maxsize)
        self._stop_evt = threading.Event()
        self._sock: socket.socket | None = None
        self._thread = threading.Thread(
            target=self._worker, name="TelnetLogWriter", daemon=daemon_thread
        )
        self._thread.start()
        print("=" * 80)
        print(f"TelnetHandler started on {host}:{port}")
        #input(f"please connect with telnet and press enter to continue...")
        print("=" * 80)
        

    def emit(self, record: logging.LogRecord) -> None:
        try:
            msg = self.format(record)
            if self.newline and not msg.endswith(self.newline):
                msg = f"{msg}{self.newline}"
            try:
                self.queue.put_nowait(msg)
            except Full:
                pass
        except Exception:
            self.handleError(record)

    def close(self) -> None:
        self._stop_evt.set()
        self._thread.join(timeout=2.0)
        if self._sock:
            try:
                self._sock.close()
            except Exception:
                pass
        super().close()

    def _connect(self):
        if not self._sock:
            self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self._sock.connect((self.host, self.port))

    def _worker(self) -> None:
        while not self._stop_evt.is_set():
            try:
                msg = self.queue.get(timeout=0.2)
            except Empty:
                continue
            try:
                self._connect()
                print("TelnetHandler: _connect success")
                input(f"please connect with telnet and press enter to continue...")
                assert self._sock is not None
                self._sock.sendall(msg.encode(self.encoding, errors="replace"))
            except Exception:
                # drop message on error, reset connection
                if self._sock:
                    try:
                        self._sock.close()
                    except Exception:
                        pass
                self._sock = None
                time.sleep(1.0)