#!/usr/bin/env python3
"""Attrappe von `rbd` - lesende Auskuenfte fuer Bildschirmfotos und Tests.

Die Kulisse enthaelt bewusst beide Zustaende, um die es beim Aufraeumen geht:

  vm-101-disk-0@auto-stuendlich-20260809-100000   geschuetzt, MIT Klon
                                                  -> muss in Ruhe gelassen werden
  vm-105-disk-0@auto-taeglich-20260809-023000     geschuetzt, OHNE Klon
                                                  -> genau der Fall, den
                                                     find_stale_protections sucht
  vm-100-disk-0@auto-taeglich-20260809-023000     ungeschuetzt
                                                  -> geht niemanden etwas an
"""

import json
import sys

# Abbild -> Elternteil (nur Klone haben einen)
ELTERN = {
    "vm-9101-disk-0": "vmdaten/vm-101-disk-0@auto-stuendlich-20260809-100000",
}

# Abbild -> [(Snapshot, geschuetzt?)]
SNAPSHOTS = {
    "vm-100-disk-0": [("auto-taeglich-20260809-023000", False)],
    "vm-101-disk-0": [("auto-taeglich-20260809-023000", False),
                      ("auto-stuendlich-20260809-100000", True)],
    "vm-105-disk-0": [("auto-taeglich-20260809-023000", True),
                      ("golden", False)],
}

POOLS = {
    "vmdaten": ["vm-100-disk-0", "vm-101-disk-0", "vm-102-disk-0",
                "vm-105-disk-0", "vm-130-disk-0",
                "vm-9101-disk-0", "vm-9102-disk-0"],
    "ctdaten": ["subvol-110-disk-0", "subvol-111-disk-0"],
}

GROESSEN = {"vm-101-disk-0": 400, "vm-105-disk-0": 250, "vm-9101-disk-0": 400}

# Optionen, hinter denen noch ein Wert steht - sonst haelt man "-m <monhost>"
# fuer den Befehl.
MIT_WERT = {"-m", "--id", "--keyring", "-c", "--conf", "-p", "--pool",
            "--namespace", "-n", "--name", "--snap", "--format"}


def zerlege(argv):
    """(Woerter ohne Optionen, {Option: Wert}) aus der Kommandozeile."""
    rest, optionen = [], {}
    index = 0
    while index < len(argv):
        wort = argv[index]
        if wort in MIT_WERT:
            optionen[wort] = argv[index + 1] if index + 1 < len(argv) else ""
            index += 2
            continue
        if wort.startswith("-"):
            optionen[wort] = True
            index += 1
            continue
        rest.append(wort)
        index += 1
    return rest, optionen


def teile(ziel):
    """pool/abbild@snap -> (abbild, snap)"""
    ohne_pool = ziel.split("/")[-1]
    abbild, _, snap = ohne_pool.partition("@")
    return abbild, snap


def kinder(abbild, snap):
    return [k for k, eltern in ELTERN.items()
            if eltern.endswith("/%s@%s" % (abbild, snap))]


def main(argv):
    rest, optionen = zerlege(argv)
    if not rest:
        return 1
    befehl = rest[0]
    ziel = rest[1] if len(rest) > 1 else ""
    abbild, snap = teile(ziel)

    if befehl == "ls":
        for name in POOLS.get(ziel or "vmdaten", []):
            print(name)
        return 0

    if befehl == "info":
        eltern = ELTERN.get(abbild)
        gigabyte = GROESSEN.get(abbild, 32)
        if optionen.get("--format") == "json":
            daten = {"name": abbild, "size": gigabyte * 1024 ** 3, "format": 2,
                     "snapshot_count": len(SNAPSHOTS.get(abbild, []))}
            if eltern:
                pool, _, rest_ = eltern.partition("/")
                bild, _, s = rest_.partition("@")
                daten["parent"] = {"pool": pool, "image": bild, "snapshot": s}
            print(json.dumps(daten))
            return 0
        print("rbd image '%s':" % abbild)
        print("\tsize %d GiB in %d objects" % (gigabyte, gigabyte * 256))
        print("\tformat: 2")
        print("\tfeatures: layering, exclusive-lock")
        if eltern:
            print("\tparent: %s" % eltern)
            print("\toverlap: %d GiB" % gigabyte)
        return 0

    if befehl == "snap" and len(rest) > 1 and rest[1] == "ls":
        abbild, _ = teile(rest[2] if len(rest) > 2 else "")
        eintraege = [{"id": nummer + 1, "name": name,
                      "size": GROESSEN.get(abbild, 32) * 1024 ** 3,
                      "protected": "true" if geschuetzt else "false"}
                     for nummer, (name, geschuetzt)
                     in enumerate(SNAPSHOTS.get(abbild, []))]
        if optionen.get("--format") == "json":
            print(json.dumps(eintraege))
        else:
            for e in eintraege:
                print("%4d %-40s %10d" % (e["id"], e["name"], e["size"]))
        return 0

    if befehl == "snap" and len(rest) > 1 and rest[1] in ("unprotect", "protect"):
        abbild, _ = teile(rest[2] if len(rest) > 2 else "")
        name = optionen.get("--snap") or ""
        vorhanden = [s for s, _ in SNAPSHOTS.get(abbild, [])]
        if name not in vorhanden:
            print("rbd: snapshot '%s' does not exist" % name, file=sys.stderr)
            return 2
        if rest[1] == "unprotect" and kinder(abbild, name):
            print("rbd: snapshot '%s' is protected from unprotection" % name,
                  file=sys.stderr)
            return 16
        return 0

    if befehl == "children":
        for kind in kinder(abbild, snap):
            print("vmdaten/%s" % kind)
        return 0

    if befehl in ("du", "flatten"):
        print("NAME                PROVISIONED  USED")
        print("%-19s      400 GiB  2.4 GiB" % abbild)
        return 0

    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
