import os
import subprocess
import signal
from subprocess import CompletedProcess
from django.dispatch import Signal, receiver


# 用于存储模拟设备的进程
# str: device_name -> CompletedProcess
SIMULATE_DEVICE_PROCESS: dict[str, CompletedProcess] = {}

start_signal = Signal(providing_args=['protocol_name', 'device_name', 'port'])
stop_signal = Signal(providing_args=['device_name'])


@receiver(start_signal)
def start_signal_callback(sender, **kwargs):
    """
    处理启动模拟设备的信号
    """
    protocol_name = kwargs.get('protocol_name')
    device_name = kwargs.get('device_name')
    device_port = kwargs.get('port')

    assert protocol_name is not None, 'protocol_name is None'
    assert device_name is not None, 'device_name is None'
    assert device_port is not None, 'device_port is None'
    
    process = subprocess.Popen(['python', 
                               f'./simulate_device_manager/simulate_devices/{protocol_name}.py', 
                               f'{device_port}'],
                               preexec_fn=os.setsid)

    SIMULATE_DEVICE_PROCESS[device_name] = process


@receiver(stop_signal)
def stop_signal_callback(sender, **kwargs):
    """
    处理关闭模拟设备的信号
    """
    device_name = kwargs.get('device_name')

    assert device_name is not None, 'device_name is None'

    process = SIMULATE_DEVICE_PROCESS.get(device_name)
    if process.poll() is None:
        os.killpg(process.pid, signal.SIGTERM) 
    del SIMULATE_DEVICE_PROCESS[device_name]
