# -*- coding: utf-8 -*-

from nanolib_helper import *
import os, datetime, sys

# ============================================================ #
nanolib_helper = NanolibHelper()
# ============================================================ #


# Callback class derived from Nlc.NlcLoggingCallback.
class LoggingCallback(Nanolib.NlcLoggingCallback): # override super class
    """
    Logging callback implementation of NlcSLoggingCallback

    Methods
    -------
    __init__(self)
        Call base class initializer
    __del__(self)
        Default destructor should be overwritten and the logging callback should be unset in
        the accessor if this object gets destroyed.
    callback(self, payload_str, formatted_str, logger_name, log_level, time_since_epoch, thread_id)
        The callback implementation that will be called from a spdlog logging instance.
    """
    
    def __init__(self):
        super().__init__()
        
        
    def __del__(self):
        """Destructor of LoggingCallback

        IMPORTANT: the member function pointer of NlcLoggingCallback::callback gets
	    bound to a std::function pointer in between (because of SWIG not supporting std::function)
	    and has to be (manually) unset/deleted in the destructor / during garbage collection!
        """
        nanolib_helper.unset_logging_callback()
        
    def callback(self, payload_str, formatted_str, logger_name, log_level, time_since_epoch, thread_id):
        """Implementation of callback function called by spdlog logging instance

        Parameters
        ----------
        payload_str : str
            The sound the animal makes (default is None)
        formatted_str : str
            Formatted message string.
        logger_name: str
            Name of the logger instance
        log_level: int
            Log level of the message
        time_since_epoch: long int 
            Time since epoch in seconds.
        thread_id: int
            Thread id of the logging thread.
        """
        print("#######################################################################################")
        print("# Payload = '" + payload_str + "'")
        print("# Formatted string = '" + formatted_str[0: formatted_str.index(os.linesep):1] + "'")
        print("# Logger name = '" + logger_name + "'")
        print("# nlc_log_level = '"  + Nanolib.LogLevelConverter.toString(log_level) + "'")
        print("# Local Time = '" + datetime.datetime.fromtimestamp(time_since_epoch).ctime() + "'")
        print("# Thread id = '" + str(thread_id) + "'")
        print("#######################################################################################")


# main
if __name__ == '__main__':
    
    # create access to the nanolib
    nanolib_helper.setup()
    
    print('Nanolib Example')

    # its possible to set the logging level to a different level
    nanolib_helper.set_logging_level(Nanolib.LogLevel_Trace)

    # list all hardware available, decide for the first one
    bus_hardware_ids = nanolib_helper.get_bus_hardware()
    
    # create logging callback instance
    loggingCallback = LoggingCallback()
    # sink (callback) log level should always be >= the common log level
    nanolib_helper.set_logging_callback(loggingCallback, Nanolib.LogLevel_Debug)
    # set function callback pointer again in accessor with other log level,
	# old callback gets released and new callback is set
    nanolib_helper.set_logging_callback(loggingCallback, Nanolib.LogLevel_Trace)

    if bus_hardware_ids.empty():
        print('No bus hardware found.')
        sys.exit(0)
        
    print('\nAvailable bus hardware:\n')

    line_num = 0
    # just for better overview: print out available hardware
    for bus_hardware_id in bus_hardware_ids:
        print('{}. {} with protocol: {}'.format(line_num, bus_hardware_id.getName(), bus_hardware_id.getProtocol()))
        line_num += 1

    
    print('')
    input('Press ENTER key to exit ...')
    
   
