#!/usr/bin/env python3
"""AdPlayr Raspberry Pi player 0.1.0. Run as the desktop user, without sudo."""
import os
from pathlib import Path
import shlex
import shutil
import subprocess
import sys

MARKER = "# AdPlayr player startup"
URL = "https://adplayr.com/player"


def startup_text(existing, command=None):
    result = []
    skip = False
    for line in existing.splitlines():
        if skip:
            skip = False
            continue
        if line == MARKER:
            skip = True
            continue
        result.append(line)
    if command:
        result.extend([MARKER, command])
    return "\n".join(result) + "\n"


def locations():
    home = Path.home()
    return (home / ".local/share/adplayr-pi", home / ".config/labwc/autostart",
            home / ".local/share/applications/adplayr-pi.desktop")


def browser():
    executable = shutil.which("chromium") or shutil.which("chromium-browser")
    if not executable:
        raise RuntimeError("Install Chromium using Raspberry Pi OS Add/Remove Software, then retry.")
    return executable


def desktop_quote(value):
    value = str(value)
    for char in ('\\', '"', '`', '$'):
        value = value.replace(char, '\\' + char)
    return '"' + value.replace('%', '%%') + '"'


def install():
    browser()
    if not (shutil.which("labwc") or shutil.which("labwc-pi")):
        raise RuntimeError("This setup requires Raspberry Pi OS Desktop with labwc.")
    root, autostart, desktop = locations()
    root.mkdir(parents=True, exist_ok=True, mode=0o700)
    installed = root / "player.py"
    if Path(__file__).resolve() != installed.resolve():
        shutil.copyfile(__file__, installed)
    autostart.parent.mkdir(parents=True, exist_ok=True)
    if autostart.exists():
        existing = autostart.read_text()
        backup = autostart.with_name("autostart.before-adplayr")
        if not backup.exists():
            shutil.copyfile(autostart, backup)
    else:
        system = Path("/etc/xdg/labwc/autostart")
        existing = system.read_text() if system.exists() else ""
    command = shlex.join([sys.executable, str(installed), "start"]) + " &"
    autostart.write_text(startup_text(existing, command))
    desktop.parent.mkdir(parents=True, exist_ok=True)
    desktop.write_text("[Desktop Entry]\nType=Application\nName=AdPlayr Player\n"
                       "Comment=Open your advert screen\nTerminal=false\nCategories=AudioVideo;\nExec="
                       + desktop_quote(sys.executable) + " " + desktop_quote(installed) + " start\n")
    print("Installed. Open AdPlayr Player from the applications menu, or sign out and back in.")
    print("Enable Desktop Auto Login and disable Screen Blanking in Raspberry Pi settings.")
    print("Close the player with Alt+F4. Existing signage programs are not changed.")


def start():
    root, _, _ = locations()
    profile = root / "browser-profile"
    profile.mkdir(parents=True, exist_ok=True, mode=0o700)
    args = [browser(), "--user-data-dir=" + str(profile), "--kiosk", "--no-first-run",
            "--no-default-browser-check", "--autoplay-policy=no-user-gesture-required", URL]
    # Retain Chromium's sandbox, pairing cookies and offline media across restarts.
    raise SystemExit(subprocess.call(args))


def uninstall():
    _, autostart, desktop = locations()
    if autostart.exists():
        autostart.write_text(startup_text(autostart.read_text()))
    desktop.unlink(missing_ok=True)
    print("Automatic startup and menu shortcut removed. Close the player with Alt+F4.")
    print("Pairing and cached media kept. Disconnect the screen in AdPlayr when retiring it.")


def main():
    if sys.platform != "linux" or os.geteuid() == 0:
        raise RuntimeError("Run this on the Pi as your normal desktop user, without sudo.")
    action = sys.argv[1] if len(sys.argv) == 2 else "install" if len(sys.argv) == 1 else ""
    if action not in ("install", "start", "uninstall"):
        raise RuntimeError("Usage: python3 AdPlayr-Pi-Setup.py [install|start|uninstall]")
    {"install": install, "start": start, "uninstall": uninstall}[action]()


if __name__ == "__main__":
    try:
        main()
    except (RuntimeError, OSError) as error:
        print(str(error), file=sys.stderr)
        sys.exit(1)
