#!/usr/bin/python

# tz_server_logger.py
#       --copyright--                   Copyright 2011 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       March 23, 2011          bar     spin off from poll_server.py
#       November 7, 2011        bar     close()
#                                       update to use zip logger and to include time_version and sync callbacks
#       November 29, 2011       bar     pyflake cleanup
#       May 27, 2012            bar     doxygen namespace
#       July 3, 2012            bar     pass log flush param down to the logger
#                                       and flush stdout on flush if stderr is not being logged
#       August 29, 2013         bar     run the start/stop entries thru our own logic so they are printed
#       September 3, 2013       bar     uh, get the stop entry out before shutting down, too
#       June 27, 2014           bar     return logged strings
#                                       {asctime}
#       --eodstamps--
##      \file
#       \namespace              tzpython.tz_server_logger
#
#
#       This is a server log file outputter.
#
#

import  os
import  sys
import  threading
import  time

import  tz_http_server
import  tz_simple_logger
import  tzlib


HTTP_PORT                   = 80

LOG_FILE_NAME       = os.path.splitext(os.path.basename(__file__))[0] + ".log"

MAX_LOG_FILE_SIZE           = 20000000
LOG_STDOUT_ERR              = False


def time_version_stamp(server_name = __file__) :
    """ Return a current time/date stamp - for log, etc. """

    server_name = server_name or __file__
    t           = time.time()

    return(" %s %f %s %s" % ( server_name, t, time.asctime(time.localtime(t)), time.tzname[0] ) )



class   a_logger(object) :

    def do_sync(me) :                                               # stub for callback to "sync" the drives - flush them out
        pass


    def __init__(me, file_name = None, http_port = None, log_stdout_err = LOG_STDOUT_ERR, on_time_version = None, on_do_sync = None, verbose = 0) :
        me.file_name        = file_name         or LOG_FILE_NAME
        me.http_port        = http_port         or 0
        me.log_stdout_err   = LOG_STDOUT_ERR if log_stdout_err is None else log_stdout_err
        me.on_time_version  = on_time_version   or time_version_stamp
        me.on_do_sync       = on_do_sync        or me.do_sync
        me.verbose          = verbose           or 0

        me.lock             = threading.RLock()
        me.logger           = None

        s                   = "Starting: %s on %s port %u" % ( me.on_time_version(), tz_http_server.get_local_ip_address(), me.http_port )
        if  me.file_name    :
            me.lock.acquire()
            me.logger       = tz_simple_logger.a_zip_logger(me.file_name)
            if  me.log_stdout_err :
                me.logger.log_stdout_err(True)
            me.log(";")
            me.log(s, flush = True)
            me.lock.release()
        else                :
            me.log(s)
        pass


    def log(me, li = "", flush = False, quiet = False) :
        """
            Write a text line out to the log and maybe print it.

            Return the logged string or None, if the string is not put to the log.
        """
        retval  = None
        if  li  :
            li  = tzlib.c_ctrl_esc(tzlib.ascii(tzlib.best_ascii(li.strip()))).replace("\\'", "'").replace('\\"', '"')

            t   = time.time()
            if  li.find("{time}") >= 0 :
                li      = li.replace("{time}", "%.1f:%.1f" % ( t, tzlib.elapsed_time(), ) )
            if  li.find("{asctime}") >= 0 :
                li      = li.replace("{asctime}", time.asctime(time.localtime(t)))

            lg  = me.logger
            if  lg :
                retval  = lg.log(li, flush = flush)
                if  flush   :
                    me.flush()
                pass
            if  (not quiet) and ((not lg) or (not me.log_stdout_err)) :
                me.lock.acquire()
                print li
                me.lock.release()
                if  flush :
                    sys.stdout.flush()
                pass
            pass
        return(retval)

    write   = log

    def verbose_log(me, li = "", level = 1, flush = False, quiet = False) :
        retval  = None
        if  level <= me.verbose :
            retval  = me.write(li, flush = flush, quiet = quiet)
        return(retval)


    def flush(me) :
        lg  = me.logger
        if  lg :
            lg.flush()
        if  not me.log_stdout_err :
            sys.stdout.flush()
        pass


    def close_log(me) :
        s                   = "Stopping: %s On %s Port %u" % ( me.on_time_version(), tz_http_server.get_local_ip_address(), me.http_port )
        me.log(s)
        me.log(";")

        me.lock.acquire()
        ( lg, me.logger )   = ( me.logger, None )
        me.log_stdout_err   = False
        me.lock.release()

        if  lg :
            lg.close()
        else :
            print s
        pass


    close   = close_log

    #   a_logger




if __name__ == '__main__' :
    pass


#
#
#
# eof
