#!/usr/bin/env python3
"""Derive a Debian package version (or channel) from a hermes-agent release tag.

Pure function; imported by scripts/termux/build_deb.sh and unit-tested by
tests/scripts/test_termux_deb_version.py (Task 4 of .hermes/plans/2026-08-31_termux-deb.md).

Mapping:
    v1.2.3                              -> 1.2.3-1
    v1.2.3+canary.20260831T120000Z      -> 1.2.3~canary.20260831T120000Z-1

The ``~`` ranks the canary below the corresponding stable in dpkg's version
ordering.

``--channel`` derives the release channel from the SAME tag regex: a tag with
a nightly timestamp is ``nightly``, everything else is ``stable``. This is the
single source of truth for the channel; workflows and other tooling must call
this instead of re-typing a case statement.
"""

from __future__ import annotations

import re
import sys

_TAG_RE = re.compile(
    r"^v(?P<major>0|[1-9]\d{0,2})\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)"
    r"(?:\+canary\.(?P<ts>20\d{6}T\d{6}Z))?$"
)


def _match_tag(tag: str) -> re.Match[str]:
    m = _TAG_RE.match(tag)
    if m is None:
        raise ValueError(
            f"malformed release tag {tag!r}: expected v<MAJOR>.<MINOR>.<PATCH> "
            "or v<MAJOR>.<MINOR>.<PATCH>+canary.<UTC timestamp>"
        )
    return m


def deb_version_for_tag(tag: str) -> str:
    """Map a release tag to its Debian version. Raises ValueError on malformed tags."""
    m = _match_tag(tag)
    base = f"{m.group('major')}.{m.group('minor')}.{m.group('patch')}"
    ts = m.group("ts")
    if ts is None:
        return f"{base}-1"
    return f"{base}~canary.{ts}-1"


def channel_for_tag(tag: str) -> str:
    """Map a release tag to its channel: 'canary' or 'stable'.

    Derived from the same _TAG_RE as deb_version_for_tag, so the two can never
    drift: a tag that yields a '~canary' deb version is canary, and the
    malformed-tag rejection is identical.
    """
    m = _match_tag(tag)
    return "canary" if m.group("ts") else "stable"


def main(argv: list[str]) -> int:
    args = argv[1:]
    channel_mode = False
    if args and args[0] == "--channel":
        channel_mode = True
        args = args[1:]
    if len(args) != 1:
        mode = "deb_version.py --channel <tag>" if channel_mode else "deb_version.py <tag>"
        print(f"usage: {mode}", file=sys.stderr)
        return 2
    try:
        print(channel_for_tag(args[0]) if channel_mode else deb_version_for_tag(args[0]))
    except ValueError as exc:
        print(f"deb_version: {exc}", file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))
