#!/usr/bin/env python3

import re
import datetime
from xml.etree import ElementTree as ET
import argparse

def parse_changelog(changelog_path):
    version_re = re.compile(r'([\d.-]+)\s+(\w+)?\s*\((\d{2}.\d{2}\.\d{2})\)')
    entry_re = re.compile(r'-\s(.*)')

    with open(changelog_path, "r", encoding="utf-8") as f:
        changelog_lines = f.read().splitlines()

    releases = []
    for l in changelog_lines:
        version_match = version_re.match(l)
        entry_match = entry_re.match(l)
        if version_match is not None:
            version, prerelease, date = version_match.groups()
            release = (version,
                       prerelease,
                       datetime.datetime.strptime(date, '%d.%m.%y').date(),
                       [])
            releases.append(release)
        elif entry_match is not None:
            release[3].append(entry_match.group(1))

    return releases

def get_release_xml(version, prerelease, date, changes):
    release = ET.Element("release")
    if prerelease is None:
        ver_str = version
    else:
        ver_str = f"{version}~{prerelease}"
    release.set("version", ver_str)
    release.set("date", date.isoformat())
    description = ET.SubElement(release, "description")
    changelist = ET.SubElement(description, "ul")
    for c in changes:
        change = ET.SubElement(changelist, "li")
        change.text = c
    return release

def get_changelog_xml(changelog, max_items=None):
    releases = ET.Element("releases")
    if max_items is not None:
        changelog = changelog[:max_items]
    for rel in changelog:
        release = get_release_xml(*rel)
        releases.append(release)
    return releases

def update_appdata(appdata_path, changelog, max_items=None):
    appdata = ET.parse(appdata_path)
    root = appdata.getroot()
    releases = root.find("releases")
    if releases is not None:
        root.remove(releases)
    root.append(
        get_changelog_xml(changelog, max_items)
    )
    appdata.write(appdata_path, encoding="utf-8", xml_declaration=True)

def main():
    ap = argparse.ArgumentParser("Parse Telegram changelog")
    ap.add_argument("-c", "--changelog-path", default="changelog.txt")
    ap.add_argument("-a", "--appdata-path", default="lib/xdg/telegramdesktop.metainfo.xml")
    ap.add_argument("-n", "--num-releases", type=int, default=None)
    args = ap.parse_args()
    update_appdata(args.appdata_path,
                   parse_changelog(args.changelog_path),
                   max_items=args.num_releases)

if __name__ == "__main__":
    main()
