import operator
from sqlalchemy import CheckConstraint, Column, DateTime, Float, Enum, ForeignKey, Integer, String
from sqlalchemy.dialects.postgresql import UUID, ARRAY
from sqlalchemy.orm import relationship
from typing import Dict
from ._Base import _Base
from .enums.QKDAppStatus import ORM_QKDAppStatusEnum
from .enums.QKDAppTypes import ORM_QKDAppTypesEnum

class AppModel(_Base):
    __tablename__ = 'app'

    app_uuid            = Column(UUID(as_uuid=False), primary_key=True)
    context_uuid        = Column(UUID(as_uuid=False), nullable=False) # Supposed to be Foreign Key
    app_status          = Column(Enum(ORM_QKDAppStatusEnum), nullable=False)
    app_type            = Column(Enum(ORM_QKDAppTypesEnum), nullable=False)
    server_app_id       = Column(String, nullable=False)
    client_app_id       = Column(ARRAY(String), nullable=False)
    backing_qkdl_uuid   = Column(ARRAY(UUID(as_uuid=False)), nullable=False)
    local_device_uuid   = Column(UUID(as_uuid=False), nullable=False)
    remote_device_uuid  = Column(UUID(as_uuid=False), nullable=True)

    # Optare: Created_at and Updated_at are only used to know if an app was updated later on the code. Don't change it

    created_at          = Column(DateTime, nullable=False)
    updated_at          = Column(DateTime, nullable=False)

    #__table_args__ = (
    #    CheckConstraint(... >= 0, name='name_value_...'),
    #)

    def dump_id(self) -> Dict:
        return {
            'context_id': {'context_uuid': {'uuid': self.context_uuid}},
            'app_uuid': {'uuid': self.app_uuid}
        }

    def dump(self) -> Dict:
        result = {
            'app_id'           : self.dump_id(),
            'app_status'       : self.app_status.value,
            'app_type'         : self.app_type.value,
            'server_app_id'    : self.server_app_id,
            'client_app_id'    : self.client_app_id,
            'backing_qkdl_id'  : [{'qkdl_uuid': {'uuid': qkdl_id}} for qkdl_id in self.backing_qkdl_uuid],
            'local_device_id'  : {'device_uuid': {'uuid': self.local_device_uuid}},
            'remote_device_id' : {'device_uuid': {'uuid': self.remote_device_uuid}},
        }
        return result
