# Path: src/booking/source/event/model/Event.py
# class Event(metaclass=ABCMeta):
# 
#     """
#     Interface that represents a generic event
#     """
# 
#     @abstractmethod
#     def get_classroom_identifier(self) -> str:
#         """Returns the classroom identifier where will be the event."""
#         pass
# 
#     @abstractmethod
#     def get_name(self) -> str:
#         """
#         Returns the name of the event
#         :rtype: str representing the name of the event
#         """
#         pass
# 
#     @abstractmethod
#     def get_description(self) -> str:
#         """Return a short description of the event"""
#         pass
# 
#     @abstractmethod
#     def get_begin(self) -> datetime:
#         """Returns the date time representing when the event start"""
#         pass
# 
#     @abstractmethod
#     def get_end(self) -> datetime:
#         """Returns the date time representing when is the event end"""
#         pass
# 
#     def __str__(self):
#         return self.get_name() + "\n" + \
#                self.get_classroom_identifier() + "\n" + \
#                str(self.get_begin()) + "\n" + \
#                str(self.get_end()) + "\n" + \
#                self.get_description()
# 
# Path: src/booking/source/event/model/EventImpl.py
# class EventImpl(Event):
# 
#     """
#     Class that implements the Event interface.
#     """
# 
#     def __init__(self, name: str, description: str, classroom_identifier: str, begin_at: datetime, end_at: datetime):
#         self._name = name
#         self._description = description
#         self._classroom_identifier = classroom_identifier
#         self._beginAt = begin_at
#         self._endAt = end_at
# 
#     def get_description(self) -> str:
#         return self._description
# 
#     def get_name(self) -> str:
#         return self._name
# 
#     def get_classroom_identifier(self) -> str:
#         return self._classroom_identifier
# 
#     def get_begin(self) -> datetime:
#         return self._beginAt
# 
#     def get_end(self) -> datetime:
#         return self._endAt
# 
# Path: src/booking/source/event/database/model/DatabaseEvent.py
# class DatabaseEvent(BaseModel):
#     class Meta:
#         db_table = 'event'
# 
#     """
#     Mysql representation of a Event
#     """
#     name = CharField(256)
#     start = DateTimeField()
#     end = DateTimeField()
#     desc = CharField(256)
#     classroom_identifier = CharField(32)


from datetime import datetime
from datetime import timedelta
from typing import List
from booking.source.event import EventsSource
from ..model import Event, EventImpl
from .model import DatabaseEvent
from booking.utils.database import get_db


class DatabaseEventsSource(EventsSource):
    def __init__(self):
        db = get_db()
        db.create_table(DatabaseEvent, safe=True)
        self._db = db

    def add_event(self, event: Event):
        DatabaseEvent.get_or_create(name=event.get_name(),
                                    start=event.get_begin(), end=event.get_end(), desc=event.get_description(),
                                    classroom_identifier=event.get_classroom_identifier())

    def get_current_event(self, classroom_identifier: str, date_time: datetime) -> Event:
        events = DatabaseEvent.select() \
            .where(DatabaseEvent.start <= date_time,
                   DatabaseEvent.end > date_time,
                   DatabaseEvent.classroom_identifier == classroom_identifier)
        event = None
        if len(events) > 0:
            event = query_result_to_event(events[0])
        return event

    def get_all_events(self):

# Path: src/booking/source/event/model/Event.py
# class Event(metaclass=ABCMeta):
# 
#     """
#     Interface that represents a generic event
#     """
# 
#     @abstractmethod
#     def get_classroom_identifier(self) -> str:
#         """Returns the classroom identifier where will be the event."""
#         pass
# 
#     @abstractmethod
#     def get_name(self) -> str:
#         """
#         Returns the name of the event
#         :rtype: str representing the name of the event
#         """
#         pass
# 
#     @abstractmethod
#     def get_description(self) -> str:
#         """Return a short description of the event"""
#         pass
# 
#     @abstractmethod
#     def get_begin(self) -> datetime:
#         """Returns the date time representing when the event start"""
#         pass
# 
#     @abstractmethod
#     def get_end(self) -> datetime:
#         """Returns the date time representing when is the event end"""
#         pass
# 
#     def __str__(self):
#         return self.get_name() + "\n" + \
#                self.get_classroom_identifier() + "\n" + \
#                str(self.get_begin()) + "\n" + \
#                str(self.get_end()) + "\n" + \
#                self.get_description()
# 
# Path: src/booking/source/event/model/EventImpl.py
# class EventImpl(Event):
# 
#     """
#     Class that implements the Event interface.
#     """
# 
#     def __init__(self, name: str, description: str, classroom_identifier: str, begin_at: datetime, end_at: datetime):
#         self._name = name
#         self._description = description
#         self._classroom_identifier = classroom_identifier
#         self._beginAt = begin_at
#         self._endAt = end_at
# 
#     def get_description(self) -> str:
#         return self._description
# 
#     def get_name(self) -> str:
#         return self._name
# 
#     def get_classroom_identifier(self) -> str:
#         return self._classroom_identifier
# 
#     def get_begin(self) -> datetime:
#         return self._beginAt
# 
#     def get_end(self) -> datetime:
#         return self._endAt
# 
# Path: src/booking/source/event/database/model/DatabaseEvent.py
# class DatabaseEvent(BaseModel):
#     class Meta:
#         db_table = 'event'
# 
#     """
#     Mysql representation of a Event
#     """
#     name = CharField(256)
#     start = DateTimeField()
#     end = DateTimeField()
#     desc = CharField(256)
#     classroom_identifier = CharField(32)


# Path: src/booking/source/event/database/DatabaseEventsSource.py
from datetime import datetime
from datetime import timedelta
from typing import List
from booking.source.event import EventsSource
from ..model import Event, EventImpl
from .model import DatabaseEvent
from booking.utils.database import get_db



class DatabaseEventsSource(EventsSource):
    def __init__(self):
        db = get_db()
        db.create_table(DatabaseEvent, safe=True)
        self._db = db

    def add_event(self, event: Event):
        DatabaseEvent.get_or_create(name=event.get_name(),
                                    start=event.get_begin(), end=event.get_end(), desc=event.get_description(),
                                    classroom_identifier=event.get_classroom_identifier())

    def get_current_event(self, classroom_identifier: str, date_time: datetime) -> Event:
        events = DatabaseEvent.select() \
            .where(DatabaseEvent.start <= date_time,
                   DatabaseEvent.end > date_time,
                   DatabaseEvent.classroom_identifier == classroom_identifier)
        event = None
        if len(events) > 0:
            event = query_result_to_event(events[0])
        return event

    def get_all_events(self):

        return query_result_to_events(DatabaseEvent.select())