{ config, pkgs, lib, ... }:

# Relevant references:
# How to prevent systemd suspend from stopping any service with a dont-sleep.service. https://askubuntu.com/q/830442/1002706

# systemctl show test-block-suspend.service -p TimeoutStopUSec
#=> TimeoutStopUSec=infinity

# systemctl cat test-block-suspend.service

# systemctl list-dependencies --before test-block-suspend.service
#=> test-block-suspend.service
#=> ├─shutdown.target
#=> ├─sleep.target
#=> │ ├─systemd-hibernate.service
#=> │ ├─systemd-hybrid-sleep.service
#=> │ ├─systemd-suspend-then-hibernate.service
#=> │ └─systemd-suspend.service
#=> └─suspend.target
#=>   └─post-resume.service

{
  # Alternative approach to adding `conflicts`, `before` and `ExecStop`.
  #
  # Immediately before entering system suspend, all executables in /usr/lib/systemd/system-sleep/ are run.
  # Execution of the sleep action is not continued until all have finished.
  # TODO: This happens after my screen got blank, wifi disabled, screen locker activated, etc.
#  environment.etc."systemd/system-sleep/test-block-suspend".source =
#    pkgs.writeShellScript "test-block-suspend" ''
#      set -eu -o pipefail
#      if [ "$1" == "pre" ]; then
#        while :; do
#          systemctl is-active --quiet test-block-suspend.service || exit 0
#          ${pkgs.coreutils}/bin/echo 'Waiting until service has finished ...'
#          ${pkgs.coreutils}/bin/sleep 1s
#        done
#      fi
#    '';

  systemd.services."test-block-suspend" = {
    description = "Inhibit suspend";

    # If suspend is initiated, this service is stopped.
    conflicts = [  "sleep.target" ];
    # Start-up of `sleep.target`
    # is delayed until this service has finished starting up.
    before = [ "sleep.target" ];

    serviceConfig = {
      # `simple`:
      #   As soon as the main process (defined in the `ExecStart`) is started (forked),
      #   start-up is considered as finished.
      # `notify`:
      #   The service sends a "READY=1" notification message via `sd_notify` when it has finished starting up.
      #   Requires `NotifyAccess`.
      #   See https://www.freedesktop.org/software/systemd/man/latest/systemd-notify.html
      Type = "notify";
      NotifyAccess = "main";

      # To stop this service `ExecStop` is run instead of sending SIGTERM to the main process of the service.
      # The command specified by `ExecStop` does never end,
      # thus stopping this service takes forever.
      # TODO: However, the sleep action continues while `ExecStop` is running. As a reslut, the system suspends.
      ExecStop = "${pkgs.coreutils}/bin/sleep infinity";
      TimeoutStopSec = "infinity";

      # This service executes a shell script as main process.
      ExecStart  = pkgs.writeShellScript "test-block-suspend-execstart" ''
        set -eu -o pipefail

        #handle_sigterm(){
        #  #while :; do
        #    printf '%s\n' 'Ignoring SIGTERM ...' >&2
        #  #  ${pkgs.coreutils}/bin/sleep 5s
        #  #done
        #}
        #trap 'handle_sigterm' TERM

        #printf '%s\n' 'Start-up 30s ...'
        #${pkgs.coreutils}/bin/sleep 30s
        systemd-notify READY=1

        while :; do
          printf '%s\n' 'Still alive'
          ${pkgs.coreutils}/bin/sleep 5s
        done
      '';
    };
  };
}
