#!/usr/bin/env python
from .base import Api
from api.util.loadscheme import LoadSchemeIterator
from common.models import Job, Server, LoadScheme, UploadToken, ApiToken, Project
from common.util.decorators import api_token_required
from common.util.clients import CacheClient
from django.http import HttpResponse, HttpResponseBadRequest
from os import path
from json import loads
import re
import uuid
import logging

cur_dir = path.dirname(path.realpath(__file__))
directory_base = '/'.join(re.split('/', cur_dir)[0:-2]) + '/'


class JobCreate(Api):
    http_method_names = ['post']

    @api_token_required
    def post(self, request):
        params = request.body
        if not params:
            return HttpResponseBadRequest('Params not set!')
        # 'task', 'person', 'tank', 'host', 'port', 'loadscheme', 'loadscheme_expanded', 'detailed_time', 'notify'
        params = loads(params)

        api_token = request.GET.get('api_token', '')
        api_token = ApiToken.objects.get(token=api_token)

        if CacheClient().get('maintenance'):
            return HttpResponse(status=423)
        needed_params = ['task', 'person', 'tank', 'host', 'port']
        for np in needed_params:  # check all parameters are set
            if np not in params:
                return HttpResponseBadRequest('%s parameter not set!' % np)
        no_tank = 0
        try:  # tank
            tank = Server.objects.get(host=params['tank'])
        except Server.DoesNotExist:  # create it
            no_tank = 1
            tank = Server(host=params['tank'], is_test=1)
            tank.save()
        # was in database and not marked as a tank - mark
        if not no_tank and not tank.is_test:
            tank.is_test = 1
            tank.save()
        try:  # target
            srv = Server.objects.get(host=params['host'])
        except Server.DoesNotExist:  # create
            srv = Server(host=params['host'])
            srv.save()
        project = Project.objects.get_or_create(owner=params['person'], name='default')[0]

        job = Job(
            project=project,
            user=api_token.user,
            tank=tank,
            srv=srv,
            srv_port=params['port'] if str(params['port']).isdigit() else 80,
            instances=0,
            name=params.get('name', ''),
            finalized=False,
        )
        job.save()

        try:
            # FIXME: Move import up after migration
            from common.models import TankUserAgent
            user_agent = request.META.get('HTTP_USER_AGENT', '').strip()
            if re.match('^(Lunapark|Uploader)/.+ YandexTank/.+ Python/.+ OS/.+', user_agent):
                TankUserAgent.objects.create(job=job, user_agent=user_agent)
        except:
            logging.exception('')

        try:  # tmp
            token = uuid.uuid4().hex
            UploadToken.objects.create(job=job.n, token=token)
        except:
            token = ''

        try:
            loadscheme = params.get('loadscheme', '')
            if loadscheme and isinstance(loadscheme, list): 
                if isinstance(loadscheme[0], dict) and 'type' in loadscheme[0]:
                    # logging.warn('Shooting via pandora. Overload isn\'t support loadscheme for pandora.')
                    schemes = ['{type}({ops},{duration})'.format(type=scheme.get('type', ''), duration=scheme.get('duration', 1), ops=','.join([str(scheme[key]) for key in sorted(scheme.keys()) if key not in ('type', 'duration')])) for scheme in loadscheme]
                    [LoadScheme(**ls).save() for ls in LoadSchemeIterator([scheme for scheme in schemes], job)]
                else:
                    [LoadScheme(**ls).save() for ls in LoadSchemeIterator([str(scheme) for scheme in loadscheme], job)]
        except Exception:
            logging.exception('Loadscheme %s is incorrect', loadscheme, exc_info=True)
            # We gat an error for jMeter's shootings. Loadscheme is a blank list
            # return HttpResponseBadRequest('loadscheme is incorrect. \
            # please note that Overload does not support fractional loadschemes yet.')

        return [{'job': job.n, 'upload_token': token}]
