from datetime import datetime, timezone
import os
import subprocess
import re

LINE_REGEX = re.compile(
    r"""(?x)
^(?P<commit>[A-Fa-f0-9]+)\s+
\(
    <(?P<email>[^>]+)>\s+
    (?P<date>[^\s]+\s[^\s]+\s[^\s]+)\s+
    (?P<line>\d+)
\)\s
(?P<content>.*)$
"""
)
VERSION_REGEX = re.compile(r"^#+\s*v?\d")


def get_unreleased_lines(file: str):
    # contains lines in the form of
    # {commit-sha} (<{email}>\s+{date}\s+{line-no}) {line}
    p = subprocess.run(
        ["git", "blame", "-e", "--date=iso", file],
        cwd=os.path.dirname(os.path.realpath(__file__)),
        text=True,
        check=True,
        capture_output=True,
    )

    unreleased_lines: list[tuple[datetime, str]] = []
    for line in p.stdout.splitlines():
        if not line:
            continue
        m = LINE_REGEX.match(line)
        assert m, f"Failed to match '{line}'"
        content = m.group("content")

        if not content:
            continue
        if content.startswith("#"):
            if VERSION_REGEX.match(content):
                break
            continue  # ignore lines with '#'

        d = datetime.fromisoformat(m.group("date"))
        d = d.astimezone(tz=timezone.utc)
        content = content.replace("- ", f"- [{d.strftime('%Y-%m-%d')}] ", 1)
        unreleased_lines.append((d, content))

    unreleased_lines.sort(key=lambda it: it[0], reverse=True)
    return unreleased_lines


def get_current_stable():
    p = subprocess.run(
        ["git", "describe", "--tags", "--abbrev=0", "--match", "v7.*.[0-9]"],
        cwd=os.path.dirname(os.path.realpath(__file__)),
        text=True,
        check=True,
        capture_output=True,
    )
    return p.stdout.strip()


print("> [!WARNING]")
print(
    "> This is an experimental version that may break. "
    "If you're looking for the latest stable release, see "
    f"https://github.com/SevenTV/chatterino7/releases/tag/{get_current_stable()}.\n"
)


unreleased_lines = get_unreleased_lines("../CHANGELOG.md")
seventv_changes = get_unreleased_lines("../CHANGELOG.c7.md")

unreleased_lines += seventv_changes
unreleased_lines.sort(key=lambda it: it[0], reverse=True)

if len(unreleased_lines) == 0:
    print("No changes since last release.")

for _, line in unreleased_lines[:5]:
    print(line)

if len(unreleased_lines) > 5:
    print("<details><summary>More Changes</summary>\n")
    for _, line in unreleased_lines[5:]:
        print(line)
    print("</details>")

if len(seventv_changes) > 0:
    print("<details><summary>Chatterino7 Changes</summary>\n")
    for _, line in seventv_changes:
        print(line)
    print("</details>")
