#!/usr/bin/env python3

"""Match the classroom's panel to the machine it is on.

There is exactly one thing about the bar that depends on hardware: a room
with no optical drive should not be offered a disc player. This edits the
one marked line in the installed layout, and nothing else.

It writes the *layout*, not the running panel. Editing
plasma-org.kde.plasma.desktop-appletsrc underneath a live plasmashell was
tried and it destroyed the panel: the shell owns that file and rewrites
it, so an edit races with it. The layout is a file the package owns and
the shell only reads, and classroom-desktop-reset makes the shell read it
again at the next login.

DVD_ENABLED is gone. A drive is something the machine can be asked about,
and asking is more reliable than remembering to edit a file when a
computer moves between rooms.
"""

import glob
import os
import re
import sys

LAYOUT = (
    "/usr/share/plasma/look-and-feel/org.ekklesia.classroom.desktop"
    "/contents/layouts/org.kde.plasma.desktop-layout.js"
)

MARKER = "/* CLASSROOM-DVD-LAUNCHER */"

# The kernel names optical drives sr0, sr1, ... regardless of bus.
DRIVE_GLOB = "/dev/sr[0-9]*"


def has_optical_drive():
    return bool(glob.glob(DRIVE_GLOB))


def rewrite(text, wanted):
    """Comment the DVD launcher in or out, idempotently."""
    line = re.compile(
        r"^(\s*)(//\s*)?(" + re.escape(MARKER) + r'\s*"applications:ekklesia-dvd\.desktop")',
        re.M,
    )

    def swap(match):
        indent, _, body = match.groups()
        return f"{indent}{'' if wanted else '// '}{body}"

    return line.sub(swap, text)


def main():
    path = sys.argv[1] if len(sys.argv) > 1 else LAYOUT

    try:
        with open(path, "r", encoding="utf-8") as handle:
            before = handle.read()
    except OSError as error:
        print(f"classroom-desktop-layout: {error}", file=sys.stderr)
        return 0

    if MARKER not in before:
        print("classroom-desktop-layout: no DVD marker in the layout",
              file=sys.stderr)
        return 0

    wanted = has_optical_drive()
    after = rewrite(before, wanted)

    if after == before:
        print(f"classroom-desktop-layout: DVD launcher already "
              f"{'present' if wanted else 'absent'}")
        return 0

    # Replace the file rather than edit in place, so a full disk or a
    # crash leaves the old layout intact rather than half of a new one.
    temporary = f"{path}.new"

    try:
        with open(temporary, "w", encoding="utf-8") as handle:
            handle.write(after)
        os.replace(temporary, path)
    except OSError as error:
        print(f"classroom-desktop-layout: {error}", file=sys.stderr)
        return 1

    print(f"classroom-desktop-layout: DVD launcher "
          f"{'added' if wanted else 'removed'}")
    return 0


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