#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.

import os
import os.path
import select
import socket

from fenrirscreenreader.core import debug
from fenrirscreenreader.core.eventData import FenrirEventType
from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver


class driver(remoteDriver):
    def __init__(self):
        remoteDriver.__init__(self)

    def initialize(self, environment):
        self.env = environment
        # Use threading instead of multiprocessing to avoid pickle issues
        # with self.env (which contains unpicklable file handles)
        self.env["runtime"]["ProcessManager"].add_custom_event_thread(
            self.watch_dog, multiprocess=False
        )

    def watch_dog(self, active, event_queue):
        # echo "command say this is a test" | nc localhost 22447
        self.fenrirSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.fenrirSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.fenrirSock.settimeout(5.0)  # Prevent hanging on slow clients
        self.host = "127.0.0.1"
        self.port = self.env["runtime"]["SettingsManager"].get_setting_as_int(
            "remote", "port"
        )
        self.fenrirSock.bind((self.host, self.port))
        self.fenrirSock.listen(1)
        while active.value:
            try:
                r, _, _ = select.select([self.fenrirSock], [], [], 0.8)
            except select.error:
                break
            if r == []:
                continue
            if self.fenrirSock in r:
                client_sock, client_addr = self.fenrirSock.accept()
                # Ensure client socket is always closed to prevent resource
                # leaks
                try:
                    try:
                        rawdata = client_sock.recv(8129)
                    except Exception as e:
                        self.env["runtime"]["DebugManager"].write_debug_out(
                            "tcpDriver watch_dog: Error receiving data from "
                            "client: "
                            + str(e),
                            debug.DebugLevel.ERROR,
                        )
                        rawdata = b""  # Set default empty data if recv fails

                    try:
                        data = rawdata.decode("utf-8").rstrip().lstrip()
                        event_queue.put(
                            {"Type": FenrirEventType.remote_incomming, "data": data}
                        )
                    except Exception as e:
                        self.env["runtime"]["DebugManager"].write_debug_out(
                            "tcpDriver watch_dog: Error decoding/queuing data: "
                            + str(e),
                            debug.DebugLevel.ERROR,
                        )
                finally:
                    # Always close client socket, even if data processing fails
                    try:
                        client_sock.close()
                    except Exception as e:
                        self.env["runtime"]["DebugManager"].write_debug_out(
                            "tcpDriver watch_dog: Error closing client socket: "
                            + str(e),
                            debug.DebugLevel.ERROR,
                        )
        if self.fenrirSock:
            self.fenrirSock.close()
            self.fenrirSock = None
