#!/usr/bin/env python3
"""Point an editorial-only SVN sync at the version already published on WordPress.org."""
import argparse
import json
import pathlib
import re
import urllib.request

SLUG = "aisthetix-virtual-try-on"
API = f"https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request%5Bslug%5D={SLUG}"
SVN = f"https://plugins.svn.wordpress.org/{SLUG}"


def fetch(url):
    with urllib.request.urlopen(url, timeout=30) as response:
        return response.read().decode("utf-8")


def header(text, name):
    values = re.findall(r"^[ \t]*(?:\*[ \t]*)?" + re.escape(name) + r":[ \t]*([^\r\n]+)", text, re.MULTILINE)
    if len(values) != 1:
        raise ValueError(f"Expected exactly one {name} header")
    return values[0].strip()


def prepare(readme, read=fetch):
    info = json.loads(read(API))
    version = info.get("version", "")
    if info.get("slug") != SLUG or not isinstance(version, str) or not re.fullmatch(r"[0-9]+(?:\.[0-9]+)+", version):
        raise ValueError("WordPress.org did not return a valid published plugin version")
    tag = f"{SVN}/tags/{version}"
    # Fail closed if the API and SVN disagree (for example during a release).
    for ref in (f"{SVN}/trunk", tag):
        if header(read(f"{ref}/{SLUG}.php"), "Version") != version:
            raise ValueError("Published API and SVN plugin versions disagree")
    if header(read(f"{tag}/readme.txt"), "Stable tag") != version:
        raise ValueError("Published tag readme does not match its version")
    previous = header(readme, "Stable tag")
    updated, count = re.subn(r"^(Stable tag:[ \t]*)[^\r\n]+", lambda match: match[1] + version, readme, flags=re.MULTILINE)
    if count != 1:
        raise ValueError("Expected exactly one plain Stable tag header in the local readme")
    return updated, {"development_stable_tag": previous, "published_stable_tag": version, "tag_url": tag}


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--readme", type=pathlib.Path, default=pathlib.Path("readme.txt"))
    parser.add_argument("--apply", action="store_true", help="Update only the Stable tag in the deployment checkout")
    args = parser.parse_args()
    original = args.readme.read_bytes().decode("utf-8")
    updated, evidence = prepare(original)
    if args.apply:
        args.readme.write_bytes(updated.encode("utf-8"))
    print(json.dumps({**evidence, "applied": args.apply}, indent=2))


if __name__ == "__main__":
    main()
