"""
Debug Toolbar middleware
"""

from __future__ import absolute_import, unicode_literals

import threading

from django.conf import settings
from django.utils.encoding import force_text
from django.utils.importlib import import_module

from debug_toolbar.toolbar import DebugToolbar
from debug_toolbar import settings as dt_settings

_HTML_TYPES = ('text/html', 'application/xhtml+xml')
# Handles python threading module bug - http://bugs.python.org/issue14308
threading._DummyThread._Thread__stop = lambda x: 1


def show_toolbar(request):
    """
    Default function to determine whether to show the toolbar on a given page.
    """
    if request.META.get('REMOTE_ADDR', None) not in settings.INTERNAL_IPS:
        return False

    if request.is_ajax():
        return False

    return bool(settings.DEBUG)


class DebugToolbarMiddleware(object):
    """
    Middleware to set up Debug Toolbar on incoming request and render toolbar
    on outgoing response.
    """
    debug_toolbars = {}

    def process_request(self, request):
        func_path = dt_settings.CONFIG['SHOW_TOOLBAR_CALLBACK']
        # Replace this with import_by_path in Django >= 1.6.
        mod_path, func_name = func_path.rsplit('.', 1)
        show_toolbar = getattr(import_module(mod_path), func_name)
        if not show_toolbar(request):
            return
        response = None
        toolbar = DebugToolbar(request)
        for panel in toolbar.enabled_panels:
            panel.enable_instrumentation()
        for panel in toolbar.enabled_panels:
            response = panel.process_request(request)
            if response:
                break
        self.__class__.debug_toolbars[threading.current_thread().ident] = toolbar
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        toolbar = self.__class__.debug_toolbars.get(threading.current_thread().ident)
        if not toolbar:
            return
        response = None
        for panel in toolbar.enabled_panels:
            response = panel.process_view(request, view_func, view_args, view_kwargs)
            if response:
                break
        return response

    def process_response(self, request, response):
        toolbar = self.__class__.debug_toolbars.pop(threading.current_thread().ident, None)
        if not toolbar or getattr(response, 'streaming', False):
            return response
        for panel in reversed(toolbar.enabled_panels):
            new_response = panel.process_response(request, response)
            if new_response:
                response = new_response
        for panel in reversed(toolbar.enabled_panels):
            panel.disable_instrumentation()
        if toolbar.config['SHOW_COLLAPSED'] and 'djdt' not in request.COOKIES:
            response.set_cookie('djdt', 'hide', 864000)
        if ('gzip' not in response.get('Content-Encoding', '') and
                response.get('Content-Type', '').split(';')[0] in _HTML_TYPES):
            content = force_text(response.content, encoding=settings.DEFAULT_CHARSET)
            try:
                insert_at = content.lower().rindex(dt_settings.CONFIG['INSERT_BEFORE'].lower())
            except ValueError:
                pass
            else:
                toolbar_content = toolbar.render_toolbar()
                response.content = content[:insert_at] + toolbar_content + content[insert_at:]
            if response.get('Content-Length', None):
                response['Content-Length'] = len(response.content)
        return response

@@ -1025,32 +1025,97 @@
 self, request):%0A
+        # Decide whether the toolbar is active for this request.%0A
         func_pat
@@ -1402,39 +1402,16 @@
  return%0A
-        response = None
 %0A       
@@ -1455,87 +1455,320 @@
     
-for panel in toolbar.enabled_panels:%0A            panel.enable_instrumentation()
+self.__class__.debug_toolbars%5Bthreading.current_thread().ident%5D = toolbar%0A%0A        # Activate instrumentation ie. monkey-patch.%0A        for panel in toolbar.enabled_panels:%0A            panel.enable_instrumentation()%0A%0A        # Run process_request methods of panels like Django middleware.%0A        response = None
 %0A   
@@ -1914,90 +1914,8 @@
 eak%0A
-        self.__class__.debug_toolbars%5Bthreading.current_thread().ident%5D = toolbar%0A
     
@@ -2135,16 +2135,86 @@
   return
+%0A%0A        # Run process_view methods of panels like Django middleware.
 %0A       
@@ -2602,78 +2602,111 @@
 lbar
- or getattr(response, 'streaming', False):%0A            return response
+:%0A            return response%0A%0A        # Run process_response methods of panels like Django middleware.
 %0A   
@@ -2899,106 +2899,768 @@
 nse%0A
-        for panel in reversed(toolbar.enabled_panels):%0A            panel.disable_instrumentation()
+%0A        # Deactivate instrumentation ie. monkey-unpatch. This must run%0A        # regardless of the response. Keep 'return' clauses below.%0A        # (NB: Django's model for middleware doesn't guarantee anything.)%0A        for panel in reversed(toolbar.enabled_panels):%0A            panel.disable_instrumentation()%0A%0A        # Check for responses where the toolbar can't be inserted.%0A        content_encoding = response.get('Content-Encoding', '')%0A        content_type = response.get('Content-Type', '').split(';')%5B0%5D%0A        if any((getattr(response, 'streaming', False),%0A                'gzip' in content_encoding,%0A                content_type not in _HTML_TYPES)):%0A            return response%0A%0A        # Collapse the toolbar by default if SHOW_COLLAPSED is set.
 %0A   
@@ -3791,24 +3791,25 @@
 864000)%0A
+%0A
         
 if ('gzi
@@ -3804,151 +3804,46 @@
     
-if ('gzip' not in response.get('Content-Encoding', '') and%0A                response.get('Content-Type', '').split(';')%5B0%5D in _HTML_TYPES):%0A    
+# Insert the toolbar in the response.%0A
     
@@ -3932,21 +3932,13 @@
     
-   
- 
 try:%0A
-    
     
@@ -4033,20 +4033,16 @@
         
-    
 except V
@@ -4052,20 +4052,16 @@
 eError:%0A
-    
         
@@ -4081,22 +4081,14 @@
     
-    
 else:%0A
-    
     
@@ -4138,20 +4138,16 @@
 olbar()%0A
-    
         

Add comments in DebugToolbarMiddleware.