""" This is the defautl context file. It replaces the Context class
    to the platform specific one.
"""
import logging
import platform
import re

logger = logging.getLogger(__name__)

# --- compatibility patch for old libs expecting inspect.getargspec (Py<3.11) ---
import inspect
from collections import namedtuple

if not hasattr(inspect, "getargspec"):
    ArgSpec = namedtuple("ArgSpec", "args varargs keywords defaults")

    def getargspec(func):
        fs = inspect.getfullargspec(func)
        return ArgSpec(fs.args, fs.varargs, fs.varkw, fs.defaults)

    inspect.getargspec = getargspec
# ---------------------------------------------------------------------------

def _get_virtio_device():
    path = None
    GUID = '{6FDE7521-1B65-48ae-B628-80BE62016026}'
    from infi.devicemanager import DeviceManager
    dm = DeviceManager()
    dm.root.rescan()
    # Search Virtio-Serial by name TODO: search by class_guid
    for i in dm.all_devices:
        if i.has_property("description"):
            if re.search("virtio.*serial", i.description, re.IGNORECASE):
                path = ("\\\\?\\" +
                        i.children[0].instance_id.lower().replace('\\', '#') +
                        "#" + GUID.lower()
                        )
                break
    logger.debug("DEV found: %s", path)
    return path

def get_context():
    system = platform.system()
    if system == "Windows":
        from windows._win32context import Context
    elif system == "Linux":
        from linux._linuxcontext import Context
    elif system == "FreeBSD":
        from freebsd._freebsdcontext import Context
    else:
        raise NotImplementedError("Platform %s is not supported.", system)
    return Context


def get_serial():
    system = platform.system()
    logger.debug("Get_serial system: %s", system)
    port = None
    if system == 'Windows':
        port = _get_virtio_device()
        import pythoncom
        pythoncom.CoInitialize()
        if port:
            from windows.win32virtio import SerialPort
        else:
            from twisted.internet.serialport import SerialPort
            port = r'\\.\COM1'
    elif system == "Linux":
        port = "/dev/virtio-ports/agent"
        try:
            logger.debug("Open!")
            open(port, 'r').close()
        except (OSError, IOError) as e:
            print(e) 
            from twisted.internet.serialport import SerialPort
            port = '/dev/ttyS0'
        else:
            from linux.posixvirtio import SerialPort
    elif system == "FreeBSD":
        port = "/dev/ttyV0.1"
        try:
            open(port, 'rw').close()
        except (OSError, IOError):
            from twisted.internet.serialport import SerialPort
            port = '/dev/ttyu0'
        else:
            from freebsd.posixvirtio import SerialPort
    else:
        raise NotImplementedError("Platform %s is not supported.", system)
    return (SerialPort, port)


class BaseContext(object):
    placed = False      # if we reciwed password or net commands
    exit_code = 0

    @staticmethod
    def postUpdate():
        return false

    @staticmethod
    def change_password(password):
        pass

    @staticmethod
    def restart_networking():
        pass

    @staticmethod
    def change_ip(interfaces, dns):
        pass

    @staticmethod
    def set_time(time):
        pass

    @staticmethod
    def set_hostname(hostname):
        pass

    @staticmethod
    def mount_store(host, username, password):
        pass

    @staticmethod
    def get_keys():
        pass

    @staticmethod
    def add_keys(keys):
        pass

    @staticmethod
    def del_keys(keys):
        pass

    @staticmethod
    def cleanup():
        pass

    @staticmethod
    def start_access_server():
        pass

    @staticmethod
    def append(data, filename, chunk_number, uuid):
        pass

    @staticmethod
    def update(filename, executable, checksum, uuid):
        pass

    @staticmethod
    def ipaddresses():
        pass

    @staticmethod
    def get_agent_version():
        try:
            with open('version.txt') as f:
                return f.readline()
        except IOError:
            return None

    @staticmethod
    def send_expiration(url):
        import notify
        notify.notify(url)
