#!/usr/bin/env python3
import glob
import html
import json
import os
import re
import shutil

import toml


def get_features(dirname):
    feature_data = {}
    for feature in sorted(os.listdir('caniuse.rs/data/' + dirname)):
        with open('caniuse.rs/data/' + dirname + '/' + feature) as f:
            name = feature.split('.')[0]
            feature_data[name] = toml.load(f)

    # new dict because we want to deduplicate features
    features = {}

    # caniuse.rs sometimes has several .toml files for one feature flag e.g.
    # For the const_io feature flag it has 6 .toml files, all with the same
    # tracking_issue_id but different titles.
    #
    # That makes sense for a search-centric application.  Not so much for a
    # static-site generator since showing the same link 6 times is confusing.
    for feat, data in feature_data.items():
        key = data['flag'] if 'flag' in data else feat

        url = None
        if 'tracking_issue_id' in data:
            url = 'https://github.com/rust-lang/rust/issues/{}'.format(
                data['tracking_issue_id']
            )
        elif 'impl_pr_id' in data:
            url = 'https://github.com/rust-lang/rust/pull/{}'.format(data['impl_pr_id'])
        elif 'stabilization_pr_id' in data:
            url = 'https://github.com/rust-lang/rust/pull/{}'.format(
                data['stabilization_pr_id']
            )
        data['url'] = url
        data['filename'] = feat

        if data['title'].startswith('the '):
            data['title'] = data['title'][len('the ') :]
        data['title'] = data['title'].replace('implementation', 'impl')

        if key in features:
            data['title'] = data['flag'].replace('_', ' ')

        if key in features and features[key]['url'] != url:
            print(
                'different urls for feature {}:\n* {}: {}\n* {}: {}'.format(
                    key,
                    data['filename'],
                    data['url'],
                    features[key]['filename'],
                    features[key]['url'],
                )
            )

        features[key] = data

    features = dict(
        sorted(features.items(), key=lambda t: t[1]['title'].replace('`', '').lower())
    )

    lib_features = {}
    non_lib_features = {}

    for key, data in features.items():
        if ('flag' in data and data['flag'] in library_flags) or 'impl for' in data[
            'title'
        ]:
            lib_features[key] = data
        else:
            non_lib_features[key] = data

    return dict(lib_features=lib_features, non_lib_features=non_lib_features)


with open('lib_feats.txt') as f:
    library_flags = set([l.strip() for l in f])

with open('caniuse.rs/data/versions.toml') as f:
    versions = toml.load(f)

for version, data in versions.items():
    try:
        data['features'] = get_features(version)
    except FileNotFoundError:
        pass

versions = dict(reversed(list(versions.items())))

unstable_features = get_features('unstable')


os.makedirs('target', exist_ok=True)
shutil.copy('style.css', 'target')
shutil.copy('script.js', 'target')

with open('target/data.json', 'w') as f:
    data = dict(unstable=dict(features=unstable_features), **versions)
    json.dump(data, f)


def write_features(f, id, features):
    if features['non_lib_features']:
        write_feature_list(f, id + '-non-lib', features['non_lib_features'])
    if features['lib_features']:
        f.write('<h3 id="{}">library</h3>'.format(id + '-lib'))
        write_feature_list(f, id + '-lib', features['lib_features'])


def write_feature_list(f, id, features):
    f.write('<ul id={}-list'.format(id))
    if len(features) > 5:
        f.write(' class=columns')
    f.write('>')
    for feat, data in features.items():
        f.write('<li><a')
        if 'flag' in data:
            f.write(' title="{}"'.format(data['flag']))
        url = data['url']
        if url:
            f.write(f' href="{url}"')
        f.write('>')
        title = html.escape(data['title'])
        title = re.sub('`(.+?)`', lambda m: '<code>{}</code>'.format(m.group(1)), title)
        f.write(title)
        f.write('</a></li>')
    f.write('</ul>')


with open('target/index.html', 'w') as f:
    with open('head.html') as h:
        f.write(h.read())

    # TODO: sort by T-lang and T-lib
    f.write('<h2 id=unstable>Unstable features</h2>')
    write_features(f, 'unstable', unstable_features)

    after_beta = False

    for version, data in versions.items():
        f.write('<div id={0} class=release>'.format(version))
        f.write('<h2>{}'.format(version))
        channel = data.get('channel')
        if after_beta:
            channel = 'stable'
            after_beta = False
        if channel:
            if channel == 'nightly':
                channel = 'stabilized'
            elif channel == 'beta':
                after_beta = True
            f.write(' [{}]'.format(channel))
        f.write('</h2>')

        if 'blog_post_path' in data:
            f.write(
                '<a class=release-notes href="https://blog.rust-lang.org/{}">{}</a>'.format(
                    data['blog_post_path'], 'release notes'
                )
            )
        f.write('</div>')

        if 'features' in data:
            write_features(f, version, data['features'])

# TODO: generate HTML