from datetime import datetime
import os, base64, json, pytz

os.makedirs(os.path.join('static', 'face'), 0o777, True)
os.makedirs(os.path.join('static', 'person'), 0o777, True)
os.makedirs(os.path.join('static', 'background'), 0o777, True)

class PunchCard2Model(object):
    # PunchCard2Model(args['method'], args['uuid'], args['mac'], args['host'], args['data'])
    def __init__(self, method, uuid, mac, host, data):
        now = datetime.now()
        if method == "accesstoken":
            self.response = {
                'Code' : 0,
                'retMsg' : "access success",
                'DataObject' : {
                    'Method': "accesstoken",
                    'tcp_port': "http://192.168.5.199:5000/punch/card2/upload",
                    'Uuid': uuid,
                    'expires_in': now.strftime('%Y-%m-%d'),
                    'Mac': mac,
                    'Token': "",
                },
            }
        if method == "sw_face_compare_push":
            self.response = {
                'code': self.SetData(data),
                'retMsg': "push success",
            }
        self.UUID = uuid
        self.MAC = mac
        self.Host = host
    def GetUUID(self): return self.UUID
    def GetPersonID(self): return self.Data['face_num'] if 'face_num' in self.Data else ""
    def GetPersonName(self): return self.Data['face_name'] if 'face_name' in self.Data else ""
    def GetPersonFace(self): return self.Data['img_data'] if 'img_data' in self.Data else ""
    def GetPersonSimilarity(self): return self.Data['match_score'] if 'match_score' in self.Data else 0
    def GetPosition(self): return self.Data['data'] if 'data' in self.Data else [ 0, 0, 0, 0 ]
    def GetCaptureTime(self): return self.Data['capture_time'] if 'capture_time' in self.Data else None
    def GetTemperature(self): return float(self.Data['temperature']) if 'temperature' in self.Data else 0
    def GetResponse(self): return self.response
    def SetData(self, data):
        data = data.replace("\'", "\"")
        data = json.loads(data) if isinstance(data, str) else data
        data['match_score'] = float(data['match_score']) / 100
        data['data'] = [ data['data']['x'], data['data']['y'], data['data']['w'], data['data']['h'] ]
        data['capture_time'] = int(data['capture_time'])
        data['capture_time'] = datetime.fromtimestamp(data['capture_time'])
        data['capture_time'] = data['capture_time'].astimezone(pytz.timezone('Asia/Taipei'))
        name = data['capture_time'].strftime('%Y_%m_%d_%H_%M_%S')
        name = "{0}_{1}".format(data['face_num'] if 'face_num' in data else "unknown", name)
        ret1, data['img_data'] = self.SaveFaceImage(name, data['img_data'])
        ret2, data['img_fr'] = self.SaveBackgroundImage(name, data['img_fr'])
        data['temperature'] = float(data['temperature']['realtime_t'])
        self.Data = data
        return 0 if ret1 and ret2 else -1001
    def SetResponse(self, code, message):
        self.response['code'] = code
        self.response['retMsg'] = message
    def SaveFaceImage(self, name, image):
        file = '{0}.jpg'.format(os.path.join('static', 'face', name))
        if not os.path.isfile(file):
            if len(image) > 0:
                try:
                    f = open(file, 'wb')
                    f.write(base64.b64decode(image))
                    f.flush()
                    f.close()
                except:
                    return False, "write image failed"
            else:
                return False, "empty iamge"
        return True, file
    def SaveBackgroundImage(self, name, image):
        file = '{0}.jpg'.format(os.path.join('static', 'background', name))
        if not os.path.isfile(file):
            if len(image) > 0:
                try:
                    f = open(file, 'wb')
                    f.write(base64.b64decode(image))
                    f.flush()
                    f.close()
                except:
                    return False, "write image failed"
            else:
                return False, "empty iamge"
        return True, file
