# coding: utf-8

import re
from distutils.version import StrictVersion

import requests
from django.core.management.base import BaseCommand

from procu.api.utils import get_tracker_client, strtobool

CHANGELOGS = {
    'f': 'https://github.yandex-team.ru/raw/tools/procu-www/master/changelog.md',
    'b': 'https://github.yandex-team.ru/raw/tools/procu/develop/changelog.md',
}

VERSION = re.compile(r'\d+(\.\d+)+')

CHANGELOG_LIMIT = 100

DESCRIPTION = """
<{{Frontend changelog
{frontend}
}}>

<{{Backend changelog
{backend}
}}>
"""


class Command(BaseCommand):
    def add_arguments(self, parser):
        pass

    @staticmethod
    def handle_component(client, component):
        versions = [
            v.name[1:]
            for v in client.queues['PROCU'].versions
            if not v.archived and v.name.startswith(component)
        ]

        assert len(versions) == 3

        # Select the middle version out of three
        return sorted(versions, key=lambda x: StrictVersion(x))[1]

    @staticmethod
    def fetch_changelog(version, component):

        url = CHANGELOGS[component]

        r = requests.get(url)
        lines = map(str.strip, r.text.split('\n'))
        changelog = []

        for line in lines:
            if re.match(r'-+', line):
                continue

            line = line.strip()

            upper = StrictVersion(version)
            upper.version = (upper.version[0] + 1, 0, 0)

            lower = StrictVersion(version)
            lower.version = (lower.version[0], 0, 0)

            if VERSION.match(line):
                if not (lower <= StrictVersion(line) < upper):
                    break

            line = re.sub(r'\[(.+?)\]\((.+?)\)', '((\\2 \\1))', line)
            line = re.sub(r'^\*\s+', '', line)
            line = re.sub(r'\[.+\]$', '', line)

            changelog.append(line)

        if len(changelog) > CHANGELOG_LIMIT:
            value = input(
                f'Changelog has more than {CHANGELOG_LIMIT} lines. '
                f'Do you want to continue? [y/N] '
            ).strip()

            if not strtobool(value):
                quit(1)

        return ('\n'.join(changelog)).strip()

    def handle(self, *args, **kwargs):

        client = get_tracker_client(base_url='https://st-api.yandex-team.ru')

        fv = self.handle_component(client, 'f')
        bv = self.handle_component(client, 'b')

        if fv != bv:
            print(f'Backend ({bv}) and frontend ({fv}) versions do not match')
            return

        release_tickets = list(
            client.issues.find(
                query=f'Queue: PROCU '
                f'AND Components: Релиз '
                f'AND "Fix Version": f{fv}, b{bv}'
            )
        )

        backend_chagelog = self.fetch_changelog(bv, 'b')
        frontend_chagelog = self.fetch_changelog(fv, 'f')

        if not (backend_chagelog or frontend_chagelog):
            print('Error: both changelogs are empty')
            return

        description = DESCRIPTION.format(
            backend=backend_chagelog, frontend=frontend_chagelog
        )

        # E.g. 5.0 turns into 5.x
        title_version = StrictVersion(fv)
        title_version.version = (title_version.version[0], 'x', 0)

        if len(release_tickets) == 0:
            issue_kwargs = dict(
                queue='PROCU',
                type={'name': 'Task'},
                summary=f'Релиз {title_version}',
                description=description,
                createdBy='mkznts',
                followers=['sofiushko', 'apioro', 'alexkoshelev'],
                components=['Backend', 'Frontend', 'Релиз'],
                fixVersions=[f'f{fv}', f'b{bv}'],
            )

            issue_kwargs['unique'] = issue_kwargs['summary']

            ticket = client.issues.create(**issue_kwargs)
            ticket.transitions['inTesting'].execute()

            print(f'Created: https://st.yandex-team.ru/{ticket.key}')

        elif len(release_tickets) == 1:
            ticket = release_tickets[0]
            ticket.update(description=description)
            print(f'Updated: https://st.yandex-team.ru/{ticket.key}')

        else:
            print(
                'Error: multiple tickets found:',
                [i.key for i in release_tickets],
            )
