#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Copyright (C) 2007-2019 Etienne Robillard <tkadm30@yandex.com>
# All rights reserved.
"""WSGI helper functions and classes for development purposes.

"""
import sys
import urllib
import logging
import time
import platform
python_impl = platform.python_implementation()

from wsgiref import simple_server, validate

from notmm.utils.configparse import string_getter, int_getter
from notmm.utils.wsgilib import translogger 
from notmm.release import BASEVERSION, MINOR_REVISION
from django.utils.termcolors import colorize as _colored
    
from .reloader import install

log = logging.getLogger(__name__)

__all__ = ('WSGIServerBase', 'BannerBase', 'get_bind_addr', 'daemonize')

class BannerBase(object):
    """This is a simple startup banner.

    Usage:
        >>> banner = BannerBase(fp=sys.stderr, ('127.0.0.1', '8000'))
        >>> banner.show()
    """

    default_format = "%Y-%m-%d %H:%M:%S %Z %z"
    debug_msg_handler = log.info

    def __init__(self, fp=debug_msg_handler, bind_addr=('127.0.0.1', '8000'),
                 settings=None):
        self.bind_addr = bind_addr
        fmt = self.get_default_format(settings)
        self.start_time = time.strftime(fmt)
        self.server_uri = 'http://%s:%i/' % bind_addr
        if not isinstance(self.bind_addr, tuple):
            raise ValueError("Error: invalid bind_addr type: %r" \
                % type(self.bind_addr))

        #assert len(self.bind_addr) == 2, \
        #    'bind_addr must contains exactly two elements'

    def get_default_format(self, settings):
        try:
            fmt = settings.DATETIME_INPUT_FORMATS[0]
        except (AttributeError, IndexError):
            return self.default_format
        else:
            return fmt
    
    def debug(self, message, color='cyan', **kwargs):
        """Write a string to the terminal with colored output"""
        self.debug_msg_handler(_colored(message, color, **kwargs))

    def show(self):
        """Override this method to handle the formatting of the banner"""

        self.debug("Initializing on %s" % self.start_time)
        self.debug("Starting HTTP server on %s" % self.server_uri)
        #colored("notmm %s "%(notmm.__version__)) 
        #colored("%s"%notmm.__copyright__)
        # XXX this part need more work ! :)
        self.debug("Django-hotsauce release %s revision %s (%s)" % (
            BASEVERSION, MINOR_REVISION, python_impl
            ))
        return self

class WSGIServerBase(object):
    """Wrapper class to configure a simple HTTP server instance"""
    
    # Uncomment this to enable cherrypy based http daemon
    # serverClass = wsgiserver.CherryPyWSGIServer
    
    serverClass = simple_server # wsgiref
    
    def __init__(self, wsgi_app, bind_addr, debug=True):
        """HTTPServer.__init__"""
        self.host = bind_addr[0]
        self.port = bind_addr[1]
        self.wsgi_app = wsgi_app
        if debug:
            # run the wsgi app in using wsgiref validator
            # middleware
            self.request_handler = validate.validator(wsgi_app)
        else:
            self.request_handler = wsgi_app

        #
        b = BannerBase(bind_addr=bind_addr)
        b.show()
    
        self.server = self.serverClass.make_server(self.host, self.port, self.request_handler)

    def serve(self):
        try:
            return self.server.serve_forever()
        except:
            raise

def get_bind_addr(app_conf, section='httpserver', listen_port=8000):
    """
    Return a 2-element tuple containing the hostname and port
    to listen for remote connections.
    """

    host = string_getter(app_conf, section, 'host') or urllib.localhost()
    port = int_getter(app_conf, section, 'port') or listen_port

    return (host, port)

def daemonize(wsgi_app, bind_addr, logging=False, autoreload=True, debug=True):
    """
    Create an instance of a validating WSGI server for 
    development purposes.
    
    XXX: enabling WSGI validation (debug=True) may trigger
    a deadlock for POST input data processing.
    """
    
    # Install translogger middleware if logging is enabled
    if logging:
        request_handler = translogger.TransLogger(wsgi_app)
    else:
        request_handler = wsgi_app
    
    # Add optional autoreloading support (see the docstring for help
    # on installing this)
    if autoreload:
        try:
            install()
        except ImportError:
            pass


    # init the wsgi server 
    server = WSGIServerBase(request_handler, bind_addr, debug=debug)

    try:
        server.serve()
    except (KeyboardInterrupt, SystemExit):
        sys.exit(0)
    except:
        raise

class HTTPServer(WSGIServerBase):
    pass
