import functools, logging
from enum import Enum
from typing import Dict
#from common.orm.fields.EnumeratedField import EnumeratedField
from common.orm.fields.ForeignKeyField import ForeignKeyField
from common.orm.fields.PrimaryKeyField import PrimaryKeyField
from common.orm.fields.StringField import StringField
from common.orm.model.Model import Model, get_related_instances
from context.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
from context.service.database.Tools import grpc_to_enum
from .ContextModel import ContextModel

LOGGER = logging.getLogger(__name__)

class ORM_ServiceTypeEnum(Enum):
    UNKNOWN                   = ServiceTypeEnum.SERVICETYPE_UNKNOWN
    L3NM                      = ServiceTypeEnum.SERVICETYPE_L3NM
    L2NM                      = ServiceTypeEnum.SERVICETYPE_L2NM
    TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE

grpc_to_enum__service_type = functools.partial(
    grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)

class ORM_ServiceStatusEnum(Enum):
    UNDEFINED       = ServiceStatusEnum.SERVICESTATUS_UNDEFINED
    PLANNED         = ServiceStatusEnum.SERVICESTATUS_PLANNED
    ACTIVE          = ServiceStatusEnum.SERVICESTATUS_ACTIVE
    PENDING_REMOVAL = ServiceStatusEnum.SERVICESTATUS_PENDING_REMOVAL

grpc_to_enum__service_status = functools.partial(
    grpc_to_enum, ServiceStatusEnum, ORM_ServiceStatusEnum)

class ServiceModel(Model):
    pk = PrimaryKeyField()
    context_fk = ForeignKeyField(ContextModel)
    service_uuid = StringField(required=True, allow_empty=False)

    def dump_id(self) -> Dict:
        context_id = ContextModel(self.database, self.context_fk).dump_id()
        return {
            'context_id': context_id,
            'service_uuid': {'uuid': self.service_uuid},
        }

    #def dump_device_ids(self) -> List[Dict]:
    #    db_device_pks = self.references(DeviceModel)
    #    return [DeviceModel(self.database, pk).dump_id() for pk in db_device_pks]

    #def dump_link_ids(self) -> List[Dict]:
    #    db_link_pks = self.references(LinkModel)
    #    return [LinkModel(self.database, pk).dump_id() for pk in db_link_pks]

    def dump(   # pylint: disable=arguments-differ
            self, include_endpoint_ids=True, include_constraints=True, include_config_rules=True
        ) -> Dict:
        result = {
            'service_id': self.dump_id(),
            'service_type': ServiceTypeEnum.Value('SERVICETYPE_UNKNOWN'),
            'service_status': ServiceStatusEnum.Value('SERVICESTATUS_UNDEFINED'),
            'service_config': {},
        }
        #if include_endpoint_ids: result['service_endpoint_ids'] = self.dump_endpoint_ids()
        #if include_constraints: result['service_constraints'] = self.dump_constraints()
        #if include_config_rules: result['service_config']['config_rules'] = self.dump_config_rules()
        return result
