# SPDX-FileCopyrightText: 2024 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

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

let
  emfminiserv = depot.go.emfminiserv;

  cfg = config.my.emfminiserv;
in
{
  options.my.emfminiserv = {
    enable = lib.mkEnableOption "emfminiserv";
    hostname = lib.mkOption {
      type = lib.types.str;
      default = "prerelease.voc.emf.camp";
    };
    listenAddresses = lib.mkOption {
      type = lib.types.nullOr (lib.types.listOf lib.types.str);
      default = null;
    };
    serveDir = lib.mkOption {
      type = lib.types.str;
      default = "/store/emf/2024/video/output/";
    };
  };

  config = lib.mkMerge [
    (lib.mkIf cfg.enable {
      users.groups.hackyplayer = {};

      systemd.services.emfminiserv = {
        serviceConfig = {
          User = "emfminiserv";
          Group = "hackyplayer";
          RuntimeDirectory = "emfminiserv";
          DynamicUser = true;
          ExecStart = "${emfminiserv}/bin/emfminiserv -http_listen_unix /run/emfminiserv/listen.sock -base_dir '${cfg.serveDir}'";
          EnvironmentFile = config.my.vault.secrets.emfminiserv-environment.path;
        };
        wantedBy = [ "multi-user.target" ];
      };

      my.vault.secrets.emfminiserv-environment = {
        reloadOrRestartUnits = ["emfminiserv.service"];
        group = "hackyplayer";
        template = ''
          {{ with secret "kv/apps/emfminiserv" }}
          {{ .Data.data.environment }}
          {{ end }}
        '';
      };

      environment.systemPackages = [
        (pkgs.writeShellApplication {
          name = "emfminiserv";
          text = ''
            read -ra vars < <(xargs <"${config.my.vault.secrets.emfminiserv-environment.path}")
            export "''${vars[@]}"
            exec "${emfminiserv}/bin/emfminiserv" -base_dir '${cfg.serveDir}' "$@"
          '';
        })
      ];

      services.caddy = {
        enable = true;
        virtualHosts."${cfg.hostname}" = {
          listenAddresses = lib.mkIf (cfg.listenAddresses != null) cfg.listenAddresses;
          extraConfig = ''
            reverse_proxy unix//run/emfminiserv/listen.sock {
              @accel header X-Accel-Redir *
              handle_response @accel {
                root    * ${cfg.serveDir}
                rewrite * {rp.header.X-Accel-Redir}
                method  * GET
                file_server
              }
            }
          '';
        };
      };
      systemd.services.caddy.serviceConfig.SupplementaryGroups = lib.mkAfter [ "hackyplayer" ];
    })
  ];
}