# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

import subprocess
import socket
import os
import sys
import queue


def run_command(command):
    try:
        result = subprocess.run(command, shell=True, check=True,
                                capture_output=True, text=True)
        logger.info(f"Command executed: {command}")
        return result.stdout
    except subprocess.CalledProcessError as e:
        logger.error(f"Error executing command {command}: {e}")
        return f"Error: {e}"


def run_action(action):
    if not config.has_section('ACTION:'+action):
        return False

    command=config.get('ACTION:'+action, 'execute', fallback=None)
    setstatus=config.get('ACTION:'+action, 'setstatus', fallback=None)
    open_outputs=config.get('ACTION:'+action, 'open.outputs', fallback=None)
    

    if setstatus:
        if setstatus in ['manual','automatic']:
        	qcore.put({'event': 'SETSTATUS', 'data': {'status': setstatus}})
        elif setstatus in ['switch','change','flip']:
            qcore.put({'event': 'CHANGESTATUS'})
    if command:
       return run_command(command)



def check_port_available(port):
    """Check if a port is available"""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(('localhost', port)) != 0


def create_daemon():
    if os.name == 'posix':  # Unix-like systems
        try:
            # First fork
            pid = os.fork()
            if pid > 0:
                # Exit first parent
                sys.exit(0)
        except OSError as err:
            logger.error(f'Fork #1 failed: {err}')
            sys.exit(1)

        # Decouple from parent environment
        os.chdir('/')
        os.setsid()
        os.umask(0)

        # Second fork
        try:
            pid = os.fork()
            if pid > 0:
                # Exit from second parent
                sys.exit(0)
        except OSError as err:
            logger.error(f'Fork #2 failed: {err}')
            sys.exit(1)

        # Redirect standard file descriptors
        sys.stdout.flush()
        sys.stderr.flush()
        si = open(os.devnull, 'r')
        so = open(os.devnull, 'a+')
        se = open(os.devnull, 'a+')
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())

    elif os.name == 'nt':  # Windows
        try:
            # Hide the console window
            si = subprocess.STARTUPINFO()
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW

            # Start the script as a new process
            subprocess.Popen([sys.executable, __file__],
                             startupinfo=si,
                             creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)

            # Exit the current process
            sys.exit(0)
        except Exception as err:
            logger.error(f'Failed to create background process: {err}')
            sys.exit(1)

    else:
        logger.error(f'Unsupported operating system: {os.name}')
        sys.exit(1)


