#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import re
import yaml

logger = logging.getLogger(__name__)


class PhantomToPandora(object):

    def __init__(self):
        self.pandora_default = {
            'enabled': False,
            'expvar': True,
            'package': 'yandextank.plugins.Pandora',
            'pandora_cmd': '/usr/local/bin/pandora'
        }

    def parse_load_profile(self, schedule):
        profile = []
        schedules = re.split(r'\) ', schedule.strip())
        for schedule in schedules:
            res = re.split(r'\(|\)|\,', schedule)

            if res[0].strip() == 'const':
                profile.append({
                    'type': 'const',
                    'ops': int(res[1].strip()),
                    'duration': res[2].strip()
                })
            elif res[0].strip() == 'line':
                profile.append({
                    'type': 'line',
                    'from': int(res[1].strip()),
                    'to': int(res[2].strip()),
                    'duration': res[3].strip()
                })
            elif res[0].strip() == 'step':
                profile.append({
                    'type': 'step',
                    'from': int(res[1].strip()),
                    'to': int(res[2].strip()),
                    'step': int(res[3].strip()),
                    'duration': res[4].strip()
                })

        return profile

    def parse_phantom_instances(self, phantom):
        startup = []
        instances = 1000
        if phantom.get('instances'):
            instances = phantom['instances']

        startup.append({
            'type': 'once',
            'times': instances
        })

        return startup

    def parse_phantom_headers(self, phantom):
        headers = []
        for header in phantom['headers']:
            headers.append('[{}]'.format(header))

        return headers

    def get_ammo_type(self, phantom):
        ammo_type = None
        if phantom.get('ammo_type'):
            if phantom['ammo_type'] == 'phantom':
                ammo_type = 'raw'
            elif phantom['ammo_type'] == 'uri':
                ammo_type = 'uri'
            else:
                ammo_type = None

        return ammo_type

    def update_phantom(self, phantom, options):
        try:
            schedule = ['phantom.rps_schedule', 'phantom.load_profile.schedule']
            for option in options:
                opt = re.split(r'=', option.strip())
                if 'phantom.address' in option:
                    phantom['address'] = opt[1]
                elif 'phantom.ammofile' in option:
                    phantom['ammofile'] = opt[1]
                elif any(s in option for s in schedule):
                    phantom['load_profile']['schedule'] = opt[1]

        except KeyError:
            pass

        return phantom

    def convert(self, raw_config, options):
        try:
            conf_yaml = yaml.safe_load(raw_config)
            pandora_yaml = conf_yaml
            if options:
                phantom = self.update_phantom(conf_yaml['phantom'], options)
            else:
                phantom = conf_yaml['phantom']

            if phantom['enabled'] is True and not phantom.get('multi')\
            and phantom.get('address')\
            and phantom['load_profile']['load_type'] == 'rps':
                if not pandora_yaml.get('pandora'):
                    pandora_yaml['pandora'] = self.pandora_default
                    pandora_yaml['phantom']['enabled'] = False
                else:
                    return raw_config, False
            else:
                return raw_config, False

            ammo_type = self.get_ammo_type(phantom)

            if phantom.get('address') and ammo_type:
                pandora_yaml['pandora'].update({
                    'config_content': {
                        'pools': [{
                            'id': 'HTTP',
                            'gun': {
                                'type': 'http',
                                'target': phantom['address']
                            },
                            'ammo': {
                                'type': ammo_type,
                                'file': phantom['ammofile']
                            },
                            'result': {
                                'type': 'phout',
                                'destination': './phout.log'
                            },
                            'rps': self.parse_load_profile(phantom['load_profile']['schedule']),
                            'startup': self.parse_phantom_instances(phantom)
                            }],
                        'log': {'level': 'error'},
                        'monitoring': {'expvar': {'enabled': True, 'port': 1234}}
                        }
                    })

                if phantom.get('headers'):
                    pandora_yaml['pandora']['config_content']['pools'][0]['ammo'].update({'headers': self.parse_phantom_headers(phantom)})

            else:
                return raw_config, False

        except (KeyError, yaml.YAMLError):
            return raw_config, False

        pandora_yaml['pandora']['enabled'] = True

        return yaml.dump(pandora_yaml, encoding=('utf-8')), True
