#!/usr/bin/env python3
"""Publish sminnee-maelstrom to PyPI.

Usage: bin/publish [--minor|--major]

Requires UV_PUBLISH_TOKEN (from environment or .env file).
"""

import argparse
import os
import re
import subprocess
import sys
from pathlib import Path


def load_token_from_env_file():
    env_file = Path(".env")
    if not env_file.exists():
        return
    for line in env_file.read_text().splitlines():
        line = line.strip()
        if line.startswith("#") or not line:
            continue
        if line.startswith("UV_PUBLISH_TOKEN="):
            value = line.split("=", 1)[1].strip().strip("\"'")
            os.environ.setdefault("UV_PUBLISH_TOKEN", value)


def get_current_version():
    text = Path("pyproject.toml").read_text()
    match = re.search(r'^version = "(.+?)"', text, re.MULTILINE)
    if not match:
        print("Error: could not find version in pyproject.toml", file=sys.stderr)
        sys.exit(1)
    return match.group(1)


def bump_version(version: str, bump: str) -> str:
    major, minor, patch = (int(x) for x in version.split("."))
    if bump == "major":
        major, minor, patch = major + 1, 0, 0
    elif bump == "minor":
        minor, patch = minor + 1, 0
    else:
        patch += 1
    return f"{major}.{minor}.{patch}"


def update_file(path: Path, old_version: str, new_version: str):
    text = path.read_text()
    updated = text.replace(f'"{old_version}"', f'"{new_version}"', 1)
    if text == updated:
        print(f"Warning: version not found in {path}", file=sys.stderr)
    path.write_text(updated)


def run(cmd: list[str]):
    result = subprocess.run(cmd)
    if result.returncode != 0:
        sys.exit(result.returncode)


def main():
    parser = argparse.ArgumentParser(description="Publish sminnee-maelstrom to PyPI")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--major", action="store_const", const="major", dest="bump")
    group.add_argument("--minor", action="store_const", const="minor", dest="bump")
    parser.set_defaults(bump="patch")
    args = parser.parse_args()

    load_token_from_env_file()

    if not os.environ.get("UV_PUBLISH_TOKEN"):
        print("Error: UV_PUBLISH_TOKEN environment variable is not set", file=sys.stderr)
        print("Get a token from https://pypi.org/manage/account/token/", file=sys.stderr)
        sys.exit(1)

    current = get_current_version()
    new_version = bump_version(current, args.bump)

    print(f"Bumping version: {current} -> {new_version} ({args.bump})")

    update_file(Path("pyproject.toml"), current, new_version)
    update_file(Path("src/maelstrom/__init__.py"), current, new_version)

    print("Building...")
    run(["uv", "build"])

    print("Publishing...")
    run(["uv", "publish"])

    run(["git", "add", "pyproject.toml", "src/maelstrom/__init__.py"])
    run(["git", "commit", "-m", f"v{new_version}"])
    run(["git", "tag", f"v{new_version}"])

    print(f"\nPublished sminnee-maelstrom {new_version}")
    print("Run 'git push && git push --tags' to push the release")


if __name__ == "__main__":
    main()
