# -*- coding: utf-8 -*-
"""
Created by chiesa

Copyright Alpes Lasers SA, Switzerland
"""
__author__ = 'chiesa'
__copyright__ = "Copyright Alpes Lasers SA"

import logging
from dataclasses import dataclass, asdict
import sys

LEVEL_SUCCESS = 'success'
LEVEL_INFO = 'info'
LEVEL_ERROR = 'error'
LEVEL_WARNING = 'warning'


def get_logging_level_from_glider_level(glider_level):
    if glider_level in [LEVEL_SUCCESS, LEVEL_INFO]:
        return logging.INFO
    if glider_level in [LEVEL_ERROR]:
        return logging.ERROR
    if glider_level in [LEVEL_WARNING]:
        return logging.WARNING
    return logging.INFO


def get_glider_level_from_logging_level(logging_level):
    if logging_level <= logging.INFO:
        return LEVEL_INFO
    elif logging_level <= logging.WARNING:
        return LEVEL_WARNING
    else:
        return LEVEL_ERROR



LEVEL_SEVERITY = [LEVEL_ERROR, LEVEL_WARNING, LEVEL_INFO, LEVEL_SUCCESS]


def _list_gli_events():
    module = sys.modules[__name__]
    return [value
        for name, value in vars(module).items()
        if name.startswith("GLI_EVENT_")]


@dataclass
class GliderEventType:
    number: int
    name: str
    level: str


@dataclass
class GliderEvent:
    uuid: str
    type: GliderEventType
    stmp: str
    sub: str = None
    message: str = None
    active: bool = True

    @property
    def display(self) -> str:
        base = f"{self.type.name} (#{self.type.number})"
        if self.message:
            return f"{base}: {self.message}"
        return base

    @classmethod
    def from_dict(cls, mydict):
        return cls(uuid=mydict['uuid'],
                   type=GliderEventType(**mydict['type']),
                   stmp=mydict['stmp'],
                   sub=mydict['sub'],
                   message=mydict['message'],
                   active=mydict['active'])

    def to_dict(self):
        data = asdict(self)
        data['display'] = self.display
        return data


GLI_EVENT_EXCURSION_USER_INTERLOCK = GliderEventType(number=101,
                                                     name="User interlock changed while initialized or executing",
                                                     level=LEVEL_ERROR)

GLI_EVENT_EXCURSION_PHYS_INTERLOCK = GliderEventType(number=102,
                                                     name="Physical interlock changed while initialized or executing",
                                                     level=LEVEL_ERROR)

GLI_EVENT_EXCURSION_TC_INTERLOCK = GliderEventType(number=103,
                                                   name="Temperature excursion while executing",
                                                   level=LEVEL_ERROR)

GLI_EVENT_PHYSICAL_INTERLOCK = GliderEventType(number=104,
                                               name="Physical interlock inactive",
                                               level=LEVEL_WARNING)

GLI_EVENT_USER_INTERLOCK = GliderEventType(number=105,
                                           name="User interlock inactive",
                                           level=LEVEL_WARNING)


GLI_EVENT_MCU_INIT_FAIL = GliderEventType(number=200,
                                          name="Unexpected system initialization failure",
                                          level=LEVEL_ERROR)
GLI_EVENT_MCU_MOTOR_TIMEOUT = GliderEventType(number=201,
                                              name="Timeout while setting emission frequency",
                                              level=LEVEL_WARNING)
GLI_EVENT_MCU_POS_OUT_OF_BOUNDS = GliderEventType(number=202,
                                                  name="Motor position of out bounds",
                                                  level=LEVEL_WARNING)
GLI_EVENT_MCU_INVALID_PARAMS = GliderEventType(number=203,
                                               name="Unexpected invalid parameters",
                                               level=LEVEL_ERROR)
GLI_EVENT_MCU_PULSE_TIMEOUT = GliderEventType(number=204,
                                              name="Timeout while setting power",
                                              level=LEVEL_WARNING)
GLI_EVENT_MCU_ANALOG2_TIMEOUT = GliderEventType(number=205,
                                            name="Timeout while acquiring external channel",
                                            level=LEVEL_WARNING)
GLI_EVENT_MCU_ANALOG1_TIMEOUT = GliderEventType(number=206,
                                            name="Timeout while acquiring external channel",
                                            level=LEVEL_WARNING)
GLI_EVENT_MCU_DMA_TIMEOUT = GliderEventType(number=207,
                                        name="Timeout while acquiring external channel",
                                        level=LEVEL_WARNING)
GLI_EVENT_MCU_UART1_TIMEOUT = GliderEventType(number=208,
                                              name="Unexpected communication timeout",
                                              level=LEVEL_ERROR)
GLI_EVENT_MCU_MSM_INVALID_STATE = GliderEventType(number=209,
                                              name="Unexpected invalid MSM state",
                                              level=LEVEL_ERROR)
GLI_EVENT_MCU_REGISTER_OVERFLOW = GliderEventType(number=210,
                                                  name="Unexpected system register overflow",
                                                  level=LEVEL_ERROR)
GLI_EVENT_MCU_ANALOG1_CLIPPING = GliderEventType(number=211,
                                                 name="Unexpected analog1 clipping",
                                                 level=LEVEL_ERROR)
GLI_EVENT_MCU_ANALOG2_CLIPPING = GliderEventType(number=212,
                                                 name="Unexpected analog1 clipping",
                                                 level=LEVEL_ERROR)
GLI_EVENT_MCU_OUT_OF_MEMORY = GliderEventType(number=213,
                                              name="Unexpected out of memory error",
                                              level=LEVEL_ERROR)



_gli_events = _list_gli_events()


if not len(set(g.number for g in _gli_events)) == len(_gli_events):
    raise ValueError("Glider events must have unique numbers")


GLI_EVENTS_TYPES = {e.number: e for e in _gli_events}

del _gli_events



