#!/usr/bin/env python
# -*- coding: utf-8 -*-
# $Id: Patch.py 9439 2015-09-25 08:01:30Z Eric $
#
# Copyright (c) 2015 Nuwa Information Co., Ltd, All Rights Reserved.
#
# Licensed under the Proprietary License,
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at our web site.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
# $Author: Eric $ (last)
# $Date: 2015-09-25 16:01:30 +0800 (Fri, 25 Sep 2015) $
# $Revision: 9439 $
#
# Contributors:
#  Bear
#  Yachu

import os

from Iuppiter.Function import enhance

from Iuno import DJANGO_VERSION

def attachDebugSettings(settingsLocals):
    """
    Attach debug related settings to settings.py.
    It must be called in settings by passing locals().

    @param settingsLocals locals() in settings.py.
    """
    pass

def extendSettings(settingsLocals):
    """
    Extend settings.

    @param settings Django project's settings module.
    """
    pass

def extendBuiltins(settingsLocals):
    """
    Extend builtins with our own.

    @param settingsLocals locals() in settings.py.
    """
    pass

def fixDjango(settingsLocals):
    """
    Fix django related bugs.

    @param settingsLocals locals() in settings.py.
    """
    from Iuppiter.Util import colored
    
    # http://www.no-ack.org/2010/07/mysql-transactions-and-django.html
    TX_LEVEL = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
    
    def promptTxFix():
        print 'init_command for MySQL is set to %s.' % TX_LEVEL
    
    def fixTx(options):
        if 'init_command' not in options:
            options['init_command'] = TX_LEVEL
            promptTxFix()
        else:
            if options['init_command'].strip() != TX_LEVEL:
                # http://stackoverflow.com/questions/12165534/
                # how-can-i-specify-multiple-init-commands-in-djangos-setup-file            
                import warnings
                
                refURL = ("http://www.no-ack.org/2010/07/"
                          "mysql-transactions-and-django.html")
                warnings.warn("'%s' %s\n%s" % (
                    colored(TX_LEVEL, 'yellow', attrs=['bold']),
                    colored(" shall be set in DATABASES init_command.", 
                            'white', attrs=['bold']),
                    colored("See %s for more details." % refURL, 
                            'cyan', attrs=['bold'])))    
    
    for k, v in settingsLocals['DATABASES'].items():
        if v.get('ENGINE', '').endswith('mysql'):
            if 'OPTIONS' not in v:
                v['OPTIONS'] = {"init_command": TX_LEVEL}
                promptTxFix()
            else:
                fixTx(v['OPTIONS'])

    if ('DATABASE_OPTION' in settingsLocals and 
        'DATABASE_ENGINE' in settingsLocals and
        settingsLocals['DATABASE_ENGINE'].endswith('mysql')):
        fixTx(settingsLocals['DATABASE_OPTION'])

def improveDjango(settingsLocals):
    """
    Do some simple stuff to improve django's performance.

    @param settingsLocals locals() in settings.py.
    """
    # We make sure we are using Python 2.5, so partial is faster than
    # django's curry function.
    #
    # After django fix the http://code.djangoproject.com/ticket/10369
    # We got problem to replace curry while rendering templates.
    # Please see http://code.djangoproject.com/ticket/12176
    #import functools
    #from django.utils import functional
    #functional.curry = functools.partial

def extendDjango(settingsLocals):
    """
    Extend django to provide the functionality we required.

    @param settingsLocals locals() in settings.py.
    """
    pass

def extendAll(settingsLocals):
    """
    Extend all about django.

    @param settingsLocals locals() in settings.py. For backward compatible, 
                          settings module is acceptable, but not recommended.
    """
    pass
    
def attachAdminURLs(settings, urlpatterns):
    """
    Attach admin related urlpatterns.
    It must be called in urls.py by passing urlpatterns.

    @param settings Django project's settings module.
    @param urlpatterns urlpatterns in urls.py.
    """
    pass

def attachDebugURLs(settings, urlpatterns):
    """
    Attach debug related urlpatterns.
    It must be called in urls.py by passing urlpatterns.

    @param settings Django project's settings module.
    @param urlpatterns urlpatterns in urls.py.
    """
    pass

def attachURLs(settings, urlpatterns):
    """
    Attach patched (for example, debug and admin...etc.) urlpatterns.
    It must be called in urls.py by passing urlpatterns.

    @param settings Django project's settings module.
    @param urlpatterns urlpatterns in urls.py.
    """
    pass

# http://www.arthurkoziel.com/2009/01/15/
# passing-mediaurl-djangos-500-error-view/

def handle500(request, template_name='500.html'):
    """
    500 error handler.

    Templates: `500.html`
    Context:
        MEDIA_URL
            Path of static media (e.g. "media.example.org")
    """
    pass
