import serial
import _thread
import time
import sys
import os

import echo_db.database as EchoDB
import echo_controller.controller as Controller

class EchoSerial:

    arduino = serial.Serial()
    allow_control = True

    @staticmethod
    def init():
        try:
            print('Starting Serial Connection with arduino...')
            # Start Serial Connection
            EchoSerial.arduino.baudrate = 115200
            EchoSerial.arduino.port = '/dev/ttyACM0'
            EchoSerial.arduino.timeout = .1
            EchoSerial.arduino.open()

            if not EchoSerial.arduino.is_open:
                print('Could not open Serial Connection with arduino!')
            
            print('Serial Connection Opened with arduino!')
            print('Starting Serial Handling Thread...')
            _thread.start_new_thread(EchoSerial.handle_serial, ("Main Serial Thread", 2, ))
        except:
            print('Error Initializing Serial Controller!')
            print('Serial Error: ' + str(sys.exc_info()[0]))
            EchoSerial.allow_control = False
            
    @staticmethod
    def handle_serial(threadname, delay):
        print('Serial Handling Thread Started!')
        while EchoSerial.arduino.isOpen():
            time.sleep(.02)
            try:
                data = EchoSerial.arduino.readline()[:-2]
                if data:
                    # Parse Incoming Data > Decode to UTF-8
                    parsed_data = data.decode("utf-8")

                    # Start new thread to handle the reponse
                    _thread.start_new_thread(EchoSerial.handle_serial_data, ("Serial Response Handler Tread", 2, parsed_data))
                    
            except:
                print('Error Occured on Serial handling Thread!')
                print('Serial Error: ' + str(sys.exc_info()[0]))
                EchoSerial.allow_control = False
                EchoSerial.reopen_serial_connection()
                # _thread.interrupt_main()
    
    @staticmethod
    def reopen_serial_connection():
        try:
            EchoSerial.arduino.close()
        except:
            print("Error closing serial connection")

        while not EchoSerial.arduino.isOpen():
            try:
                EchoSerial.arduino.open()
            except:
                print("Error reopening serial connection")
            finally:
                time.sleep(1)
        
        EchoSerial.allow_control = True
        print("Serial Connection Established!")
        
    @staticmethod
    def handle_serial_data(threadNamee, delay, data):
        # Command Example:
        # 9472-4f60:temp_data:data
        # Data is if needed separated by ,
        print('Parsing Packet: ' + data)

        # Remove packet Markers
        data = data[1:-1]

        # Parse command
        parsed_data = data.split(':')

        # Check if startup command
        if parsed_data[0] == "0":
            print('Echo Controller Ready!')
            return
        
        # Check if startup command
        if parsed_data[0] == "1":
            print('Echo LED Controller Ready!')
            return

        # Get Device
        collection = EchoDB.EchoDB.database['Devices']
        device = collection.find_one({'uuid': parsed_data[0]})

        # Send to controller
        Controller.Controller.handle_output_device(device, parsed_data[1], parsed_data)

    @staticmethod
    def send_serial(command):
        # Command Example:
        # 9472-4f60:get_data:data
        # data is if needed separated by ,
        EchoSerial.arduino.write(command.encode())

    @staticmethod
    def send_commmand(device, action, value = "0"):
        serial_command = "<" + device['uuid'] + ":" + action + ":" + value + ">"
        print('Sending Packet: ' + serial_command)
        EchoSerial.send_serial(serial_command)
        


                    


