from abc import ABCMeta, abstractmethod
from ._DeviceServiceThread import DeviceServiceThread
from nperipherals_core.model.repository import NotificationRepository
from typing import Optional
from nperipherals_core.model.device_status import DeviceStatus


class Device(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def get_name(self):
        # type: () -> str
        raise NotImplementedError()

    @abstractmethod
    def initialize(self):
        # type: () -> None
        raise NotImplementedError()

    @abstractmethod
    def connect(self):
        # type: () -> None
        raise NotImplementedError()

    @abstractmethod
    def disconnect(self):
        # type: () -> None
        raise NotImplementedError()

    @abstractmethod
    def get_status(self):
        # type: () -> DeviceStatus
        raise NotImplementedError()

    def _create_service_thread(self, repository):
        # type: (NotificationRepository) -> Optional[DeviceServiceThread]
        pass

    def get_service_thread(self, repository):
        # type: (NotificationRepository) -> Optional[DeviceServiceThread]
        if getattr(self, "_service_thread", None) is None:
            # noinspection PyAttributeOutsideInit
            self._service_thread = self._create_service_thread(repository)
        return self._service_thread
