from datetime import timedelta

from django.core.management.base import BaseCommand
from django.utils import timezone
from library.python import resource
from yql.api.v1.client import YqlClient
from yql.client.parameter_value_builder import YqlParameterValueBuilder

from intranet.search.core.utils import get_oauth_token
from intranet.search.core.storages.job_storage import job_status


class Command(BaseCommand):
    help = 'Base task for calculations with YQL and Libra'
    default_period = 1
    job_name = ''
    yql_script_name = ''
    yql_attachments_files = ['libra_parse_utils.py']

    def add_arguments(self, parser):
        parser.add_argument('--date-from', action='store',  default='',
                            help='Start date for calculating')
        parser.add_argument('--date-to', action='store', default='',
                            help='End date for calculating')

    def handle(self, **options):
        @job_status(name=self.job_name or self.yql_script_name)
        def inner(**options):
            date_to = options.get('date_to') or self.get_default_date_to()
            date_from = options.get('date_from') or self.get_default_date_from(date_to)

            data = self.get_yql_data(date_from, date_to)
            self.save_data(data)
        inner(**options)

    def get_default_date_from(self, date_to):
        return date_to - timedelta(days=self.default_period)

    def get_default_date_to(self):
        return timezone.now().date() - timedelta(days=1)

    def get_yql_data(self, date_from, date_to):
        query = resource.find(self.yql_script_name).decode('utf-8')
        params = {
            '$date_from': YqlParameterValueBuilder.make_string(str(date_from)),
            '$date_to': YqlParameterValueBuilder.make_string(str(date_to)),
        }

        client = YqlClient(token=get_oauth_token('oauth_yql'))
        request = client.query(query, syntax_version=1)
        for attachment in self.yql_attachments_files:
            file_data = resource.find(attachment)
            request.attach_file_data(file_data, attachment)
        request.attach_url(
            'yt://hahn/statbox/statbox-dict-last/blockstat.dict',
            'blockstat.dict'
        )
        request.run(parameters=YqlParameterValueBuilder.build_json_map(params))

        data = []
        for table in request.get_results():
            table.fetch_full_data()
            column_names = [col[0] for col in table.columns]

            for row in table.rows:
                data.append(dict(zip(column_names, row)))
        return data

    def save_data(self, data):
        pass
