#!/usr/bin/env bash

# What closing the lid should do.
#
#   panama-lid status    what this machine would do right now, as JSON
#   panama-lid guard     hold the inhibitor while clamshell use is possible
#
# The rule is one sentence: closing the lid should suspend, UNLESS there is an
# external monitor, in which case the machine is docked and should keep working.
#
# The implementation is deliberately not a lid watcher. logind already handles
# the lid perfectly well; what it cannot do is notice that an external display
# makes a closed lid mean something different, because its own "docked" test
# looks for an ACPI docking station that modern hardware does not have.
#
# So Panama does not take the lid over. It holds a `handle-lid-switch`
# inhibitor while an external monitor is connected, and releases it when the
# last one goes away. logind does everything else, which has three properties
# worth having:
#
#   * Nothing has to watch the lid, and no polling loop exists.
#   * If this ever fails or is killed, the inhibitor is released and the
#     machine goes back to logind's default. The failure mode is "a docked
#     laptop suspends", not "the lid does nothing at all", which is the failure
#     mode a logind drop-in would have.
#   * Locking before sleep is already handled: hypridle's before_sleep_cmd
#     runs `loginctl lock-session`, so a suspend from a closed lid is a locked
#     suspend without anything here being involved.
#
# Started and stopped by services/LidPolicy.qml on display topology changes.
#
# NOT YET VERIFIED ON A LAPTOP. The logic and the inhibitor are testable on any
# machine and are covered by tests/setup/lid-contract, but the end-to-end
# behavior of closing a real lid on a docked machine needs a machine with a
# lid. Everything here fails toward logind's default, so the untested path is
# "keeps working while docked" rather than anything that could strand a session.

set -uo pipefail

PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
HW="$PANAMA_PATH/bin/panama-hw"

answer() { "$@" && printf 'true' || printf 'false'; }

cmd_status() {
    local inhibited=false
    systemd-inhibit --list 2>/dev/null | grep -q 'panama-lid' && inhibited=true
    printf '{"laptop":%s,"lidClosed":%s,"externalMonitor":%s,"clamshell":%s,"inhibited":%s}\n' \
        "$(answer "$HW" laptop)" \
        "$(answer "$HW" lid-closed)" \
        "$(answer "$HW" external-monitor)" \
        "$(answer "$HW" clamshell)" \
        "$inhibited"
}

# Holds the inhibitor for as long as it runs. Exits immediately, holding
# nothing, when this machine has no reason to want one -- a desktop has no lid
# to inhibit and an undocked laptop should suspend normally.
cmd_guard() {
    "$HW" laptop || exit 0
    "$HW" external-monitor || exit 0

    exec systemd-inhibit \
        --what=handle-lid-switch \
        --who=panama-lid \
        --why="An external display is connected, so a closed lid is a docked machine rather than one being put away" \
        --mode=block \
        sleep infinity
}

case "${1:-status}" in
    status) cmd_status ;;
    guard)  cmd_guard ;;
    -h|--help)
        cat <<'USAGE'
usage: panama-lid [status|guard]

  status   what closing the lid would do right now, as JSON
  guard    hold a handle-lid-switch inhibitor while an external display is
           connected; exits immediately on a machine that needs none
USAGE
        ;;
    *) printf 'panama-lid: unknown command: %s\n' "$1" >&2; exit 2 ;;
esac
