#!/usr/bin/env python3
"""Generate UUIDs without uuid-runtime.

A uuidgen(1) work-alike covering the forms the image hooks use, so the only
dependency is python3, which rpi-image-gen already requires. uuid-runtime
would otherwise be pulled in for this alone, and it enables uuidd.socket.

  iguuid                                     random, version 4
  iguuid --sha1 --namespace NS --name NAME   name-based, version 5
  iguuid --md5  --namespace NS --name NAME   name-based, version 3

As with uuidgen, the default is version 4. NS is a UUID, or one of the
well-known aliases @dns, @url, @oid, @x500.
"""

import argparse
import sys
import uuid

ALIASES = {
    "@dns": uuid.NAMESPACE_DNS,
    "@url": uuid.NAMESPACE_URL,
    "@oid": uuid.NAMESPACE_OID,
    "@x500": uuid.NAMESPACE_X500,
}


def main():
    ap = argparse.ArgumentParser(prog="iguuid", description=__doc__)
    ap.add_argument("-r", "--random", action="store_true")
    ap.add_argument("-s", "--sha1", action="store_true")
    ap.add_argument("-m", "--md5", action="store_true")
    ap.add_argument("-n", "--namespace")
    ap.add_argument("-N", "--name")
    args = ap.parse_args()

    if args.sha1 and args.md5:
        ap.error("--sha1 and --md5 are mutually exclusive")

    if args.sha1 or args.md5:
        if args.namespace is None or args.name is None:
            ap.error("--namespace and --name are required for a name-based UUID")
        ns = ALIASES.get(args.namespace.lower())
        if ns is None:
            try:
                ns = uuid.UUID(args.namespace)
            except ValueError:
                ap.error(f"not a UUID or known namespace: {args.namespace}")
        gen = uuid.uuid5 if args.sha1 else uuid.uuid3
        print(gen(ns, args.name))
        return

    if args.namespace is not None or args.name is not None:
        ap.error("--namespace/--name need --sha1 or --md5")

    print(uuid.uuid4())


if __name__ == "__main__":
    sys.exit(main())
