import collections
import copy
import io
import logging
import os
import sys
import tarfile

import requests

import util


def yield_candidates():
    for page in range(1, 100):
        url = f'https://api.github.com/repos/ClickHouse/ClickHouse/tags?per_page=100&page={page}'
        for candidate in requests.get(url).json():
            yield candidate


def choose_latest_releases(args):
    logging.info('Collecting release candidates')
    seen = collections.OrderedDict()
    candidates = []
    stable_count = 0
    lts_count = 0

    for tag in yield_candidates():
        if isinstance(tag, dict):
            name = tag.get('name', '')
            is_stable = 'stable' in name
            is_lts = 'lts' in name
            is_unstable = not (is_stable or is_lts)
            is_in_blacklist = ('v18' in name) or ('prestable' in name) or ('v1.1' in name)
            if is_unstable or is_in_blacklist:
                continue
            major_version = '.'.join((name.split('.', 2))[:2])
            if major_version not in seen:
                if (stable_count >= args.stable_releases_limit) and (lts_count >= args.lts_releases_limit):
                    break

                payload = (name, tag.get('tarball_url'), is_lts,)
                if is_lts:
                    if lts_count < args.lts_releases_limit:
                        seen[major_version] = payload
                    lts_count += 1
                else:
                    if stable_count < args.stable_releases_limit:
                        seen[major_version] = payload
                    stable_count += 1

            logging.debug(
                f'Stables: {stable_count}/{args.stable_releases_limit} LTS: {lts_count}/{args.lts_releases_limit}'
            )
        else:
            logging.fatal('Unexpected GitHub response: %s', str(candidates))
            sys.exit(1)

    logging.info('Found stable releases: %s', ', '.join(seen.keys()))
    return seen.items()


def process_release(args, callback, release):
    name, (full_name, tarball_url, is_lts,) = release
    logging.info(f'Building docs for {full_name}')
    buf = io.BytesIO(requests.get(tarball_url).content)
    tar = tarfile.open(mode='r:gz', fileobj=buf)
    with util.temp_dir() as base_dir:
        tar.extractall(base_dir)
        args = copy.copy(args)
        args.version_prefix = name
        args.is_stable_release = True
        args.docs_dir = os.path.join(base_dir, os.listdir(base_dir)[0], 'docs')
        callback(args)


def build_releases(args, callback):
    for release in args.stable_releases:
        process_release(args, callback, release)


def get_events(args):
    events = []
    skip = True
    with open(os.path.join(args.docs_dir, '..', 'README.md')) as f:
        for line in f:
            if skip:
                if 'Upcoming Events' in line:
                    skip = False
            else:
                if not line:
                    continue
                line = line.strip().split('](')
                if len(line) == 2:
                    tail = line[1].split(') ')
                    events.append({
                        'signup_link': tail[0],
                        'event_name':  line[0].replace('* [', ''),
                        'event_date':  tail[1].replace('on ', '').replace('.', '')
                    })
    return events


if __name__ == '__main__':
    class DummyArgs(object):
        lts_releases_limit = 1
        stable_releases_limit = 3
    logging.basicConfig(
        level=logging.DEBUG,
        stream=sys.stderr
    )
    for item in choose_latest_releases(DummyArgs()):
        print(item)