"""
Created on Sep 3, 2014

@author: noob
"""

import codecs
from django.http import HttpResponseBadRequest, HttpResponse, HttpResponseServerError, StreamingHttpResponse
import logging
import requests
from json import dumps, loads
from common.models import Job
from settings import MDS_GET_ARTEFACT_URL


def auth_proxy(request):
    source = request.GET.get('source', '')
    if source == 'tankapi':
        client = TankapiClient(request)
        return client.get()
    elif source == 'mds':
        client = MDStorageClient(request)
        return client.get()
    else:
        return HttpResponseBadRequest()


def get_user_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


class TankapiClient(object):
    def __init__(self, request):
        self.request = request

    def get(self):
        try:
            tank = self.request.GET.get('tank', '')
            file_type = self.request.GET.get('file', '')
            tankapi_job = self.request.GET.get('tajob', '')
            lunapark_job = self.request.GET.get('lpjob', '')
            assert all([lunapark_job, tankapi_job, file_type, tank])
            lunapark_job_obj = Job.objects.get(n=lunapark_job)
            configinfo = lunapark_job_obj.config
            tankapi_port = configinfo.get('meta', {}).get('use_tank_port') or \
                           configinfo.get('uploader', {}).get('meta', {}).get('use_tank_port', '8083')
            url = 'http://{}:{}/api/v1/tests/{}/logs/{}'.format(tank, tankapi_port, tankapi_job, file_type)
            resp = requests.get(url, stream=True, timeout=10)
            content_type = resp.headers['content-type']
            text = ''
            decoder = codecs.getincrementaldecoder('utf-8')()
            for chunk in resp.iter_content(chunk_size=1024):
                if chunk:
                    text += decoder.decode(chunk)
                    assert len(text) < 5 * 10 ** 8  # 500 MB tankapi doesn't send content-length :(
            if not self.request.GET.get("download"):
                if content_type == "application/octet-stream":
                    try:
                        json = loads(text)
                        response = HttpResponse(dumps(json), content_type="appication/json")
                        response['Content-Disposition'] = \
                            'inline; filename={}__{}'.format(lunapark_job, url.split("/")[-1])
                    except:
                        response = HttpResponse(text, content_type="text/plain")
                        response['Content-Disposition'] = \
                            'inline; filename={}__{}'.format(lunapark_job, url.split("/")[-1])
                else:
                    response = HttpResponse(text, content_type=content_type)
                    response['Content-Disposition'] = 'inline; filename={}__{}'.format(lunapark_job, url.split("/")[-1])
            else:
                response = HttpResponse(text, content_type=content_type)
                response['Content-Disposition'] = 'attachment; filename={}__{}'.format(lunapark_job, url.split("/")[-1])
            return response
        except AssertionError:
            return HttpResponseBadRequest()


class MDStorageClient(object):
    def __init__(self, request):
        self.request = request

    def get(self):
        try:
            artifact = self.request.GET.get('artifact', '')
            assert artifact
            url = MDS_GET_ARTEFACT_URL.format(artifact)
            headers = {'Authorization': 'Basic bG9hZC1hcnRlZmFjdDpmMDM3ZWI3NDU2YzcxM2JiMGU0YWE2NjUxM2ZlOWJmNw=='}
            resp = requests.get(url, headers=headers)
            content_type = resp.headers['content-type']
            if not self.request.GET.get('download'):
                if content_type == 'application/octet-stream':
                    try:
                        json = loads(resp.text)
                        response = StreamingHttpResponse(dumps(json), content_type='appication/json')
                        response['Content-Disposition'] = 'inline; filename={}' .format(url.split("/")[-1])
                    except:
                        response = StreamingHttpResponse(resp.text, content_type='text/plain')
                        response['Content-Disposition'] = 'inline; filename={}'.format(url.split("/")[-1])
                else:
                    response = StreamingHttpResponse(resp.text, content_type=content_type)
                    response['Content-Disposition'] = 'inline; filename={}'.format(url.split("/")[-1])
            else:
                response = HttpResponse(resp.text, content_type=content_type)
                response['Content-Disposition'] = 'attachment; filename={}'.format(url.split("/")[-1])
            return response
        except AssertionError:
            return HttpResponseBadRequest()
        except:
            logging.exception("")
            return HttpResponseServerError()
