# -*- coding: utf-8 -*-
from itertools import izip_longest
import logging
from os import remove
from os.path import basename, join
import traceback as tb
from campaign_class import Campaign, DirCampaign, StaticCampaign
from errs import GeoError, GroupError, TemplateError
from task import get_camp_options, get_extra_negative_keywords, read_standart_task, read_direction_task
from utils import gen_tmp_name, get_tmp_path, make_camp_file, make_zip_file

logger = logging.getLogger(__name__)


def campaign_builder(task_path):
    logger.info(u'{} in progress'.format(basename(task_path)))

    results, result = [], None
    try:
        options = get_camp_options(task_path)
        if options['local_category'] == 'tickets':
            params = read_direction_task(task_path, options)
        else:
            params = read_standart_task(task_path)

        results = builder(params, options)

        if results:
            result = make_zip_file(results, u'{}_{}.zip'.format(gen_tmp_name(), basename(task_path).split('.')[0]))

    except (GeoError, GroupError) as exc:
        logger.error(u'{}: bad geo/ads in task!'.format(basename(task_path)))

        result = join(get_tmp_path(), u'{}_bad_task.txt'.format(gen_tmp_name()))
        with open(result, 'w') as fd:
            fd.write(exc.message.encode('utf-8'))
    except TemplateError as exc:
        logger.error(u'{}: bad {} template!'.format(basename(task_path), exc.where))

        result = join(get_tmp_path(), u'{}_bad_template.txt'.format(gen_tmp_name()))
        with open(result, 'w') as fd:
            fd.write(exc.message.encode('utf-8'))

    except:
        logger.exception(task_path)
        if results:
            for file_ in results:
                remove(file_)

        result = join(get_tmp_path(), u'{}_error.txt'.format(gen_tmp_name()))
        with open(result, 'w') as fd:
            fd.write(tb.format_exc())

    if result:
        logger.info(u'{} completed: result {}'.format(basename(task_path), basename(result)))

    return result


def builder(params, options):
    class_ = DirCampaign if options['local_category'] == 'tickets' else Campaign
    results = []

    if options['local_category'] == 'tickets':
        ads = []
        for camp_name in ['Origins', 'Destinations', 'Locations']:
            camp_options = options.copy()
            camp_options['negative_keywords'] = get_extra_negative_keywords(camp_name, params, options)

            camp = StaticCampaign(camp_name, camp_options, params[camp_name.lower()], params['codes'])
            camp.build()
            ads += camp.ads

        f_path = make_camp_file(u'static.csv', ads)
        logger.info(u'{} generated'.format(basename(f_path)))
        results.append(f_path)

    for f_num, slice_ in enumerate(izip_longest(fillvalue=None, *[iter(params['geo_list'])] * 10), 1):
        slice_ = [geo_dict for geo_dict in slice_ if geo_dict]

        ads = []
        for geo in slice_:
            camp = class_(options.copy(), geo, codes=params.get('codes'))
            camp.build()
            ads += camp.ads

        f_path = make_camp_file(u'{}_{}.csv'.format(gen_tmp_name(), f_num), ads)

        logger.info(u'{} generated'.format(basename(f_path)))
        results.append(f_path)

    return results
