"""
Set-up function. Initiates the communication interface.
"""
import sys
from typing import Union

from tmtc_core.comIF.obsw_com_interface import CommunicationInterface
from tmtc_core.comIF.obsw_dummy_com_if import DummyComIF
from tmtc_core.comIF.obsw_ethernet_com_if import EthernetComIF
from tmtc_core.comIF.obsw_serial_com_if import SerialComIF, SerialCommunicationType
from tmtc_core.comIF.obsw_qemu_com_if import QEMUComIF

from tmtc_core.utility.obsw_logger import get_logger
from tmtc_core.utility.obsw_tmtc_printer import TmTcPrinter

import config.obsw_config as g

LOGGER = get_logger()


def set_communication_interface(tmtc_printer: TmTcPrinter) -> Union[CommunicationInterface, None]:
    """
    Return the desired communication interface object
    :param tmtc_printer: TmTcPrinter object.
    :return: CommunicationInterface object
    """
    try:
        if g.G_COM_IF == g.ComIF.Ethernet:
            communication_interface = EthernetComIF(
                tmtc_printer=tmtc_printer, tm_timeout=g.G_TM_TIMEOUT,
                tc_timeout_factor=g.G_TC_SEND_TIMEOUT_FACTOR, send_address=g.G_ETHERNET_SEND_ADDRESS,
                receive_address=g.G_ETHERNET_RECV_ADDRESS)
        elif g.G_COM_IF == g.ComIF.Serial:
            serial_baudrate = g.G_SERIAL_BAUDRATE
            serial_timeout = g.G_SERIAL_TIMEOUT
            communication_interface = SerialComIF(
                tmtc_printer=tmtc_printer, com_port=g.G_COM_PORT, baud_rate=serial_baudrate,
                serial_timeout=serial_timeout,
                ser_com_type=SerialCommunicationType.DLE_ENCODING)
            communication_interface.set_dle_settings(
                g.G_SERIAL_DLE_MAX_QUEUE_LEN, g.G_SERIAL_DLE_MAX_FRAME_SIZE, serial_timeout)
        elif g.G_COM_IF == g.ComIF.QEMU:
            communication_interface = QEMUComIF(
                tmtc_printer=tmtc_printer, tm_timeout=g.G_TM_TIMEOUT,
                tc_timeout_factor=g.G_TC_SEND_TIMEOUT_FACTOR)
        else:
            communication_interface = DummyComIF(tmtc_printer=tmtc_printer)
        if not communication_interface.valid:
            LOGGER.warning("Invalid communication interface!")
            sys.exit()
        communication_interface.initialize()
        return communication_interface
    except (IOError, OSError):
        LOGGER.error("Error setting up communication interface")
        LOGGER.exception("Error")
        sys.exit()