# -*- coding: utf-8 -*-
# Copyright (C) 2000-2006  Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
This is a hotfix, it dynamically applies several patches to Zope.
"""

# Import from the Standard Library
import logging
import os
import six

# Import from itools
from .itools.i18n import AcceptLanguageType

# Import from Zope
from ZPublisher.HTTPRequest import HTTPRequest
from zope.globalrequest import clearRequest, setRequest
from zope.globalrequest import getRequest as get_request

# Flag
patch = False
Z_DEBUG_MODE = os.environ.get('Z_DEBUG_MODE') == '1'


logger = logging.getLogger('Localizer')


# PATCH 1: Global Request
#
# The original purpose was to get the request object from places where the
# acquisition was disabled (within the __of__ method for example). It was
# inspired by the Tim McLaughlin's GlobalGetRequest proposal, see
# http://dev.zope.org/Wikis/DevSite/Proposals/GlobalGetRequest
#
# Currently it keeps a Context instance, which wraps the request object,
# but also other things, like the user's session, as it is required by
# the ikaaro CMS.
#
# The request objects are stored in a dictionary in the Publish module,
# whose keys are the thread id.
#
# Also, we keep the get_request method in the Globals module for backwards
# compatibility (with TranslationService for example).

def get_new_publish(zope_publish):
    def publish(request, *args, **kwargs):
        try:
            setRequest(request)
            return zope_publish(request, *args, **kwargs)
        finally:
            clearRequest()
    return publish


if patch is False:
    patch = True

    if six.PY2: # ZServer-specific patch
      logger.info('Install "Globals.get_request".')

      # Apply the patch
      from ZPublisher import Publish
      Publish.publish = get_new_publish(Publish.publish)

      # Add to Globals for backwards compatibility 
      import Globals
      Globals.get_request = get_request


# PATCH 2: Accept
#
# Adds the variable AcceptLanguage to the REQUEST.  It provides a higher
# level interface than HTTP_ACCEPT_LANGUAGE.

# Apply the patch
def new_processInputs(self):
    HTTPRequest.old_processInputs(self)

    request = self

    # Set the AcceptLanguage variable
    # Initialize with the browser configuration
    accept_language = request['HTTP_ACCEPT_LANGUAGE']
    # Patches for user agents that don't support correctly the protocol
    user_agent = request['HTTP_USER_AGENT']
    if user_agent.startswith('Mozilla/4') and user_agent.find('MSIE') == -1:
        # Netscape 4.x
        q = 1.0
        langs = []
        for lang in [ x.strip() for x in accept_language.split(',') ]:
            langs.append('%s;q=%f' % (lang, q))
            q = q/2
        accept_language = ','.join(langs)

    accept_language = AcceptLanguageType.decode(accept_language)
    self.other['AcceptLanguage'] = accept_language


if patch:
    HTTPRequest.old_processInputs = HTTPRequest.processInputs
    HTTPRequest.processInputs = new_processInputs