# Path: src/booking/source/user/UserSource.py
# class UserSource(ABC):
#     """
#     Class that represents a source used to store and get the user that use the bot.
#     """
# 
#     @abstractmethod
#     def get_user_by_identifier(self, identifier: int) -> User:
#         """
#         Gets the user that have the identifier equal to the provided identifier.
#         :param identifier: Identifier used to get the user.
#         :return: Return the user that have the requested identifier, if the user is not present will return None.
#         """
#         pass
# 
#     def get_all_users(self) -> List[User]:
#         """
#         Gets all the users.
#         :return: Return a list of all the users.
#         """
#         pass
# 
#     def add_user(self, user: User):
#         """
#         Adds a user.
#         :param user: User that will be added.
#         :return:
#         """
#         pass
# 
# Path: src/booking/source/user/User.py
# class User:
# 
#     class Role(Enum):
#         USER = 0
#         ADMIN = 1
# 
#         def __new__(cls, value):
#             member = object.__new__(cls)
#             member._value = value
#             return member
# 
#         def __int__(self):
#             return self._value
# 
#     def __init__(self, username: str, name: str, surname: str, identifier: int, role: Role = Role.USER):
#         self._username = escape_none(username)
#         self._name = escape_none(name)
#         self._surname = escape_none(surname)
#         self._identifier = identifier
#         self._role = role
# 
#     def get_username(self) -> str:
#         return self._username
# 
#     def get_name(self) -> str:
#         return self._name
# 
#     def get_surname(self) -> str:
#         return self._surname
# 
#     def get_identifier(self) -> int:
#         return self._identifier
# 
#     def get_role(self) -> Role:
#         return self._role
# 
#     def set_role(self, role: Role):
#         self._role = role
# 
# Path: src/booking/source/user/database/DatabaseUser.py
# class DatabaseUser(BaseModel):
#     class Meta:
#         db_table = 'user'
# 
#     """
#     Database representation of a User
#     """
#     username = CharField(64, default='')
#     name = CharField(64, default='')
#     surname = CharField(64, default='')
#     identifier = IntegerField()
#     role = IntegerField()


from booking.utils.database import get_db
from ..UserSource import UserSource
from ..User import User
from .DatabaseUser import DatabaseUser
from typing import List


class DatabaseUserSource(UserSource):

    def __init__(self):
        db = get_db()
        db.create_table(DatabaseUser, safe=True)
        self._db = db

    def add_user(self, user: User):
        username = escape_none(user.get_username())
        name = escape_none(user.get_name())
        surname = escape_none(user.get_surname())
        DatabaseUser.get_or_create(username=username, name=name, surname=surname,
                                   identifier=user.get_identifier(), role=int(user.get_role()))

    def get_user_by_identifier(self, identifier: int) -> User:

# Path: src/booking/source/user/UserSource.py
# class UserSource(ABC):
#     """
#     Class that represents a source used to store and get the user that use the bot.
#     """
# 
#     @abstractmethod
#     def get_user_by_identifier(self, identifier: int) -> User:
#         """
#         Gets the user that have the identifier equal to the provided identifier.
#         :param identifier: Identifier used to get the user.
#         :return: Return the user that have the requested identifier, if the user is not present will return None.
#         """
#         pass
# 
#     def get_all_users(self) -> List[User]:
#         """
#         Gets all the users.
#         :return: Return a list of all the users.
#         """
#         pass
# 
#     def add_user(self, user: User):
#         """
#         Adds a user.
#         :param user: User that will be added.
#         :return:
#         """
#         pass
# 
# Path: src/booking/source/user/User.py
# class User:
# 
#     class Role(Enum):
#         USER = 0
#         ADMIN = 1
# 
#         def __new__(cls, value):
#             member = object.__new__(cls)
#             member._value = value
#             return member
# 
#         def __int__(self):
#             return self._value
# 
#     def __init__(self, username: str, name: str, surname: str, identifier: int, role: Role = Role.USER):
#         self._username = escape_none(username)
#         self._name = escape_none(name)
#         self._surname = escape_none(surname)
#         self._identifier = identifier
#         self._role = role
# 
#     def get_username(self) -> str:
#         return self._username
# 
#     def get_name(self) -> str:
#         return self._name
# 
#     def get_surname(self) -> str:
#         return self._surname
# 
#     def get_identifier(self) -> int:
#         return self._identifier
# 
#     def get_role(self) -> Role:
#         return self._role
# 
#     def set_role(self, role: Role):
#         self._role = role
# 
# Path: src/booking/source/user/database/DatabaseUser.py
# class DatabaseUser(BaseModel):
#     class Meta:
#         db_table = 'user'
# 
#     """
#     Database representation of a User
#     """
#     username = CharField(64, default='')
#     name = CharField(64, default='')
#     surname = CharField(64, default='')
#     identifier = IntegerField()
#     role = IntegerField()


# Path: src/booking/source/user/database/DatabaseUserSource.py
from booking.utils.database import get_db
from ..UserSource import UserSource
from ..User import User
from .DatabaseUser import DatabaseUser
from typing import List



class DatabaseUserSource(UserSource):

    def __init__(self):
        db = get_db()
        db.create_table(DatabaseUser, safe=True)
        self._db = db

    def add_user(self, user: User):
        username = escape_none(user.get_username())
        name = escape_none(user.get_name())
        surname = escape_none(user.get_surname())
        DatabaseUser.get_or_create(username=username, name=name, surname=surname,
                                   identifier=user.get_identifier(), role=int(user.get_role()))

    def get_user_by_identifier(self, identifier: int) -> User:

        sql_users = DatabaseUser.select().where(DatabaseUser.identifier == identifier)