#!usr/bin/python3
import json
import threading
import time
import paho.mqtt.client as mqtt
import subprocess
import os
from module.slog import slog


class smqtt:
    def __init__(self,  mqtt_info):
        self._log = slog()
        self._topic_enable = False
        self._topic = []
        self._mqtt_enable = False
        self._mqtt_info = mqtt_info
        self._client = None
        self._start_flag = False
        self._rcv_event = threading.Event()
        self._config_event = threading.Event()
        self._data = None
        self._updata_data = None
        self._cnt = 0
        self._totalPack = 0

    def open_mqtt(self):
        # open mqtt
        try:
            if 'user' in self._mqtt_info and 'password' in self._mqtt_info \
                    and 'broker' in self._mqtt_info and 'port' in self._mqtt_info:
                self._client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
                self._client.username_pw_set(self._mqtt_info['user'], self._mqtt_info['password'])        
                self._client.on_connect = self.on_connect
                self._client.on_message = self.on_message

                self._client.connect(self._mqtt_info['broker'], self._mqtt_info['port'])
                self._mqtt_enable = True
                self._log.info("mqtt config success")
            else:
                self._mqtt_enable = False
                self._log.error("mqtt config error")
        except Exception as exp:
            self._mqtt_enable = False
            self._log.error(exp)

    def set_add_topic(self, topic):
        self._topic_enable = True
        self._topic.append(topic)

    def get_add_topic(self):
        if self._topic_enable:
            return self._topic
        else:
            return None

    def clear_topic(self):
        del self._topic
        self._topic = []
        self._topic_enable = False

    def on_connect(self, client, userdata, flags, rc):
        if self._topic_enable and self._mqtt_enable:
            for index in self._topic:
                self._client.subscribe(index)
                print(index)
        self._start_flag = True

    def on_message(self, client, userdata, msg):
        try:
            if self._topic_enable and self._mqtt_enable:
                if "ConfigRM" in msg.topic:
                    data = str(msg.payload, encoding="utf-8")
                    data = eval(data)
                    if 'pack_id' in data:
                        if data["pack_id"] == 0:
                           self._cnt = 0
                           self._totalPack = -1
                           del self._updata_data
                           self._updata_data = None
                           self._updata_data = data
                           bStatus = True
                        else:
                            if self._cnt ==  data["pack_id"]:
                                for index in data["config"]:
                                    self._updata_data['config'].append(index)
                                bStatus = True  
                            else:
                                bStatus = False 
                        if 'totalPack' in data:
                            self._totalPack = data["totalPack"]

                        if  self._cnt == self._totalPack:
                            self._totalPack = 0
                            bStatus = True
                            self.set_rcv_event()
                        self._cnt = self._cnt + 1
                        
                        if bStatus is True:
                            ConfigResponse = {"ss":[{"result":{"code":0,"message":"success"}}]}
                        else:
                            ConfigResponse = {"ss":[{"result":{"code":0,"message":"error"}}]}
                       
                        self.publish(msg.topic + 'Response', ConfigResponse)

                    
                   

        except Exception as exp:
            print(exp)

    def publish(self, config_topic, data):
        try:
            if self._client._state != 2 and self._mqtt_enable:
                self._client.publish(config_topic,  json.dumps(data, separators=(',', ':')), qos=1)
        except Exception as exp:
            self._log.error(exp)

    def set_rcv_event(self):
        if self._rcv_event is not None:
            self._rcv_event.set()

    def wait_rcv_event(self):
        if self._rcv_event is not None:
            self._rcv_event.wait()

    def clear_rcv_event(self):
        if self._rcv_event is not None:
            self._rcv_event.clear()

    def set_config_event(self):
        if self._config_event is not None:
            self._config_event.set()

    def wait_config_event(self):
        if self._config_event is not None:
            self._config_event.wait()

    def clear_config_event(self):
        if self._config_event is not None:
            self._config_event.clear()

    def get_rcv_data(self):
        return self._updata_data 

    def loop_task(self):
        try:
            if self._mqtt_enable:
                self._client.loop_start()
        except Exception as exp:
            self._log.error(exp)

    def del_task(self):
        try:
            if self._mqtt_enable:
                self._client.loop_stop()
        except Exception as exp:
            self._log.error(exp)

    def internet_task(self, dev):
        connec_status = False
        while True:
            try:
                fnull = open(os.devnull, 'w')
                if dev != "Windows":
                    r = subprocess.call('sudo ping -c 1 ' + self._mqtt_info['broker'], shell=True, stdout=fnull, stderr=fnull)
                else:
                    r = subprocess.call('ping ' + self._mqtt_info['broker'], shell=True, stdout=fnull, stderr=fnull)
                if r:
                    if connec_status is True:
                        self._client.disconnect()
                        self.del_task()
                        connec_status = False
                        self._log.info("通信失败")     
                else:
                    if connec_status is False:
                        self._client.username_pw_set(self._mqtt_info['user'], self._mqtt_info['password'])        
                        self._client.connect(self._mqtt_info['broker'], self._mqtt_info['port'])
                        if self._topic_enable and self._mqtt_enable:
                            for index in self._topic:
                                self._client.subscribe(index)
                                print(index)
                        self.loop_task()
                        connec_status = True
                        self._log.info('正常联网')
            except Exception as exp:
                print(exp)
            time.sleep(60)