import sys
from concurrent.futures import ThreadPoolExecutor

sys.path.append("..")
# 导入pymysql
import socket
import threading
import time
from datetime import datetime


import google.protobuf.text_format as tf


import message_pb2 as message
from led_protocol import LedProtocol
from led_protocol import font_library


class led_control(threading.Thread):
    def __init__(self, unit, channel,communication, area_list):
        threading.Thread.__init__(self)
        self._dispatch_statu = {}
        self.led_communication = communication
        self.area_list = area_list
        self.statu_string = ""
        self.parking_string = ""

        self.db =db
        self.unit = unit
        self.channel = channel
        self.led_protocol = LedProtocol(area_list)
        self._pool = ThreadPoolExecutor(max_workers=11)

    def led_control_init(self):
        unit_char = ""
        if self.unit == 1:
            unit_char = 'A'
        elif self.unit == 2:
            unit_char = 'B'
        elif self.unit == 11:
            unit_char = 'A1'
        elif self.unit == 12:
            unit_char = 'A2'
        elif self.unit == 13:
            unit_char = 'A3'
        elif self.unit == 14:
            unit_char = 'A4'
        elif self.unit == 21:
            unit_char = 'BA1'
        elif self.unit == 22:
            unit_char = 'B2'
        elif self.unit == 23:
            unit_char = 'B3'
        elif self.unit == 24:
            unit_char = 'B4'
        elif self.unit == 25:
            unit_char = 'B5'
        elif self.unit == 31:
            unit_char = 'C1'
        elif self.unit == 32:
            unit_char = 'C2'
        self.send_led_msg(0, unit_char,en_font=font_library["EN32"])

    def receive_dispatch_statu(self, statu, ex, key):
        self._dispatch_statu[key] = statu
    def get_parking_string(self,small_space_res,big_space_res):

        led_show_string = "剩大车位:%d\\n剩小车位:%d" % ( len(big_space_res), len(small_space_res))
        return led_show_string

    def get_entrance_statu_led_string(self,key,small_space_res,big_space_res):
        led_show_string = ""
        if (key in self._dispatch_statu) is False or self._dispatch_statu[key].timeout():
            print('ERROR --- 调度节点未连接----key:%s---------time:%s' % (key, datetime.now()))
            led_show_string = "故障！！"
        else:
            dispatch_node_statu = message.dispatch_node_statu()
            try:
                tf.Parse(self._dispatch_statu[key].statu, dispatch_node_statu)
                if dispatch_node_statu.plc_carrier_status == 0:
                    led_show_string =  "故障！！"
                elif dispatch_node_statu.plc_carrier_status == 4:
                    led_show_string =  "维护中！"
                else:
                    if  len(big_space_res)<=0 and len(small_space_res)<=0:
                        led_show_string = "无位 不可进\\n限高: 0.00"
                    elif len(big_space_res)>0 and dispatch_node_statu.dispatch_plc_passway_status_vector[self.channel-1].plc_passway_enable == 0:
                        led_show_string = "占用 不可进\\n限高: 2.00"
                    elif len(big_space_res)>0 and dispatch_node_statu.dispatch_plc_passway_status_vector[self.channel-1].plc_passway_enable == 1:
                        led_show_string = "空闲 可进入\\n限高: 2.00"
                    elif len(small_space_res)>0 and dispatch_node_statu.dispatch_plc_passway_status_vector[self.channel-1].plc_passway_enable == 0:
                        led_show_string = "占用 不可进\\n限高: 1.50"
                    elif len(small_space_res)>0 and dispatch_node_statu.dispatch_plc_passway_status_vector[self.channel-1].plc_passway_enable == 1:
                        led_show_string = "空闲 可进入\\n限高: 1.50"
            except Exception:
                print('ERROR --- 调度状态消息解析错误  key:%s   time:%s    message:\n%s' % (
                key, datetime.now(), self._dispatch_statu[key].statu))
                led_show_string = "故障！！"

        return led_show_string

    def send_led_msg(self, area_index, input, en_font=font_library["EN16"], cn_font=font_library["CN16"]):
        t_time = datetime.now()
        while (datetime.now() - t_time).microseconds < 30000:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            try:
                sock.connect((self.led_communication['ip'], self.led_communication['port']))
                sock.send(self.led_protocol.string2bytes(area_index, input, en_font, cn_font))
                print("connected led \033[0:32mSUCCEND\033[m ip:%s   port:%d\nsend msg area_index:%d   msg:%s" % (
                    self.led_communication['ip'], self.led_communication['port'], area_index, input))
                break
            except Exception as e:
                print("connected led \033[0:31mERROR\033[m: %s    time:%s   msg=%s" % (str(e.args),datetime.now(),input))
            time.sleep(0.01)
        sock.close()
        time.sleep(0.1)

    def run(self):
        self.led_control_init()
        key = "dispatch_%d_statu_port" % self.unit
        while True:
            small_space_res = self.db.query_space_in_height_unit_and_empty(1.48,self.unit)
            big_space_res = self.db.query_space_in_height_unit_and_empty(1.50,self.unit)
            statu_string = self.get_entrance_statu_led_string(key,small_space_res,big_space_res)

            if self.statu_string != statu_string:
                self.statu_string = statu_string
                self._pool.submit(self.send_led_msg,1, self.statu_string)

            parking_string = self.get_parking_string(small_space_res,big_space_res)
            if self.parking_string != parking_string:
                self.parking_string = parking_string
                # self.send_led_msg(2, self.parking_string)
                self._pool.submit(self.send_led_msg,2, self.parking_string)

            time.sleep(1)

