from collections import namedtuple
from enum import Enum
import numpy as np

# The enumerate of response states
class ResState(Enum):
  OK = 'ok'            # Success without error
  REJECT = 'reject'    # The invaild request has been rejected
  PENDING = 'pending'  # The request is pending
  ERROR = 'error'      # Have trouble
  NOTFOUND = 'notfound'# There's no user match that face

# The enumerate of request type
class ReqType(Enum):
  NOP = 'nop'    # Default operation
  RECOG = 'recog'  # Request the system to recognize the face
  NEW = 'new'    # Request the system to train new model with new face

# The message that carry picture from front-end-server to deep-unit.
# 
# req_id: Request ID to identify requests in whole subsystem. Generated by front-end-server.
# req_type: The type of this request. See enumerate ReqType above.
# img: The numpy array of raw image. The shape of the array is (160,160,3).
# label: The userID of new faces. req_type==ReqType.NEW
PictureMsg = namedtuple("PictureMsg", "req_id req_type img label")

# The message carry feature from deep-unit to recog-scheduler.
#
# req_id: Same as PictureMsg.
# req_type: Same as PictureMsg.
# res_state: The result state of deep-unit. See enumerate ResState above.
# face_id: The feature result from deep-unit. It's a numpy array. Shape is (1792, 1)
# label: Same as PictureMsg
FeatureMsg = namedtuple("FeatureMsg", "req_id req_type res_state face_id label")

# The message carry recognize request from recog-scheduler to recog-unit
#
# req_id: Same as FeatureMsg.
# face_id: Same as FeatureMsg.
RecogMsg = namedtuple("RecogMsg", "req_id face_id")

# The message carry recognize result from recog-unit to front-end-server
# This message also indicate success new face recognition of deep-unit
#
# req_id: Same as RecogMsg.
# res_state: The state of recognition result.
# user_id: If res_state is ResState.OK. This field should be present.
UserIDMsg = namedtuple("UserIDMsg", "req_id res_state user_id")

# The message carry training request from recog-scheduler to train-unit
#
# label: Same as FeatureMsg.
# face_id: 10 of face_id of single user.
TrainMsg = namedtuple("TrainMsg", "label face_id")

# The message carry trained model from train-unit to recog-unit
#
# serial: The serial number of this model. Use unix time stamp.
# The weight of model, FaceID DB and ANN are all stored in MongoDB.
DeployModelMsg = namedtuple("DeployModelMsg", "serial")