"""
views that handle reverse proxy
"""

from django.http import HttpResponse
from django.conf import settings
from django.core.servers.basehttp import _hop_headers
from httplib2 import Http, urlparse

def proxy(request):
    """
    reverse proxy function
    """
    target_url = join_url(request.get_full_path(), request.is_secure())
    http = Http()
    http.follow_redirects = False 
    headers = {}
    if request.COOKIES:
        cookie_value = clone_cookies(request.COOKIES)
        headers = {'Cookie': cookie_value}

    headers['Content-Type'] = request.META['CONTENT_TYPE'] 
    httplib2_response, content = http.request(target_url, request.method, body=request.raw_post_data, headers=headers)
    mime_type = httplib2_response['content-type']
    response = HttpResponse(content, status=httplib2_response.status, mimetype=mime_type)

    update_response_header(response, httplib2_response)

    if httplib2_response.status in [302]:
        url = httplib2_response['location']
        masked_location = masked_url(url, request.get_host())
        response['location'] = masked_location
    return response 

def join_url(path, is_secure=False):
    """
    return tartget_url of origin server
    """
    protocol = 'http'
    if is_secure:
        protocol = 'https'
    return  ('%s://%s%s') % (protocol, settings.ORIGIN_SERVER, path)

def masked_url(url, host):
    """
    Mask given url with host

    http://www.google.com/search?... -> http://<host>/search?... 
    """
    splited_url = urlparse.urlsplit(url)
    # _replace is an only method to edit properties of namedtuple :(
    # pylint: disable=E1103,W0212
    # no error
    masked_splited_url = splited_url._replace(netloc = host)
    # pylint: enable=E1103,W0212 
    # error
    return masked_splited_url.geturl()
 
def clone_cookies(request_cookies):
    """
    return value to be set in Cookie header to pass on
    """
    cookies = []
    for key, value in request_cookies.items():
        cookies.append('%s=%s' % (key, value))
    cookie_value = ';'.join(cookies)
    return cookie_value

def update_response_header(response, headers):
    """
    update response header with given headers

    ignore hop headers to avoid django hop-by-hop assertion error
    """
    ignored_keys = ['status', 'content-location'] + _hop_headers.keys()
    for key, value in headers.items():
        if key not in ignored_keys:
            response[key] = value

