#!/usr/bin/python

import sys
sys.path.append('/home/root/SeaCloudScripts')
import logging
import lib_system
from subprocess import CalledProcessError
import ctypes
import os
from time import sleep
import lib_logger

logger = logging.getLogger()

# Local UI modes
UI_MODE_OFF = 0
UI_MODE_UPDATE = 1
UI_MODE_ERROR = 2
UI_MODE_SUCCESS = 3
UI_MODE_REBOOT = 4

wrapper_library_name = "libLocalUISeaCloudWrapper.so"
try:
    local_UI_wrapper = ctypes.CDLL(wrapper_library_name)
except OSError as e:
    local_UI_wrapper = None


def init_local_UI( mode = None ):
    '''
    Initializes the SeaCloud local UI. It gets the wrapper to the UI library, and starts the LocalUIProcess
    @mode: the mode to set the local UI upon initialization
    return local_UI_wrapper, the wrapper to get access to UI library functions
    '''
    global local_UI_wrapper

    logger.info("Init local UI")
    if local_UI_wrapper is None:
        logger.warning("Error while loading wrapper library {}".format(wrapper_library_name))

    try:
        os.system("/usr/local/bin/LocalUIProcess &")
        os.system("/usr/local/bin/Watchdog &")
        sleep(1)
    except OSError as e:
        logger.warning("Error while starting LocalUIProcess")
        local_UI_wrapper = None  

    set_UI_mode(mode)
    return local_UI_wrapper
        

def shut_down_local_UI():
    '''
    Stops the SeaCloud local UI. It switches off the local UI, and kill the LocalUIProcess
    @local_UI_wrapper: the wrapper to get access to UI library functions
    '''
    logger.info("shut down local UI")
    try:
        set_UI_mode(UI_MODE_SUCCESS)  #switch off LEDs
        sleep(1)
        (_, output) = lib_system.call_shell(["killall","-q","LocalUIProcess"])
        (_, output) = lib_system.call_shell(["killall","-q","Watchdog"])
    except CalledProcessError as e:
        logger.error("Unable to stop LocalUIProcess")   
        

def set_UI_mode( mode ):
    '''
    Set UI mode
    @local_UI_wrapper: the wrapper to get access to UI library functions
    @mode: the mode to set the local UI to
    '''
    if local_UI_wrapper is None:
        logger.warning("LocalUI wrapper missing. UI not updated.")
        return
    elif mode is None:
        return

    try:
        if mode == UI_MODE_OFF:
            local_UI_wrapper.SetFwBeingUpdatedState(False)
        elif mode == UI_MODE_UPDATE:
            local_UI_wrapper.SetFwBeingUpdatedState(True)
        elif mode == UI_MODE_ERROR:
            local_UI_wrapper.SetFwUpdateResult(False)
        elif mode == UI_MODE_REBOOT or mode == UI_MODE_SUCCESS:
            local_UI_wrapper.SetFwUpdateResult(True)
        else:
            logger.warning("Unsupported UI mode: {}".format(mode))
    except AttributeError as e:
        logger.warning("LocalUI wrapper entry point missing. UI not updated.")


NEBULA_CLIENT_UNKNOWN = 0						# NebulaClient is not running. We cannot say noting: no success, no fail. This state has to be ignored.
NEBULA_CLIENT_REGISTERING = 1					# NebulaClient is running (trying to register to nebula)
NEBULA_CLIENT_REGISTRATION_FAILED = 2			# Registration at Nebula Cloud failed
NEBULA_CLIENT_REGISTRATION_FAILED_FID = 3		# Registration at Nebula Cloud failed because FID is unknown
NEBULA_CLIENT_REGISTRATION_FAILED_CLAIMED = 4	# Registration at Nebula Cloud failed because already claimed
NEBULA_CLIENT_REGISTRATION_OK = 5				# Registration at Nebula Cloud succeeded

def get_nebula_state():
	'''
	Return the Nebula state reported by NebulaClient
	'''
	return local_UI_wrapper.GetNebulaState();


SEND_DAEMON_UNKNOWN = 0				# initialization state is unknown (at program start)
SEND_DAEMON_INITIALIZING = 1		# initialization in progress (checking Internet connection and authentication to Cloud)
SEND_DAEMON_ERROR = 2				# initialization finished in error
SEND_DAEMON_ERROR_AMQP = 3			# amqp.json file is missing or corrupted
SEND_DAEMON_OK = 4					# cloud connection is OK
SEND_DAEMON_INTERNET_AVAILABLE = 5  # Internet connection is available (but we may don't know yet if cloud is OK)
SEND_DAEMON_INTERNET_DOWN = 6		# Internet connection is not available
SEND_DAEMON_INTERNET_CHECKING = 7	# Internet Monitor thread is checking connection

def get_mqsenddaemon_state():
	'''
	Return the MqSendDaemon state
	'''
	return local_UI_wrapper.GetMqSendDaemonState();

CLOUD_STATE_DOWN = 0					# Internet is not available
CLOUD_STATE_ERROR = 1					# cloud module is in error
CLOUD_STATE_ERROR_AMQP = 2				# cloud module is in error due to bad or missing amqp.json
CLOUD_STATE_ERROR_ALREADY_CLAIMED = 3	# cloud module is in error due to already claimed
CLOUD_STATE_ERROR_FID = 4				# cloud module is in error due to FID not found
CLOUD_STATE_ATTEMPT = 5					# Connection is being established
CLOUD_STATE_INTERNET_ONLY = 6			# Internet OK, but Cloud connection KO (authentication failed)
CLOUD_STATE_OK = 7						# Cloud connection OK

def get_cloud_state():
	'''
	Return the CloudConnectionState
	'''
	return local_UI_wrapper.GetCloudState();
