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

let
  inherit (depot.ops) secrets;
  sock = "/run/fup.sock";
  pkg = depot.web.fup;
in
{
  options = with lib; {
    my.fup.listen = lib.mkOption {
      type = with types; listOf str;
      default = [ "127.0.0.1" "[::1]" ];
    };
  };

  config = {
    my.vault.acmeCertificates."p.lukegb.com" = {
      hostnames = [ "p.lukegb.com" ];
      caddyVirtualHosts = [ "p.lukegb.com" ];
    };
    services.caddy = {
      virtualHosts."p.lukegb.com" = {
        extraConfig = ''
          ${lib.optionalString (config.my.fup.listen != []) "bind ${lib.concatStringsSep " " config.my.fup.listen}"}
          reverse_proxy unix/${sock}
        '';
      };
    };

    users.users.fup = { isSystemUser = true; group = "fup"; };
    users.groups.fup = {};

    systemd.sockets.fup = {
      listenStreams = [ sock ];
      wantedBy = [ "sockets.target" ];
      socketConfig = {
        SocketUser = config.services.caddy.user;
        SocketGroup = config.services.caddy.group;
        SocketMode = "0700";
      };
    };

    systemd.services.fup = {
      wantedBy = [ "multi-user.target" ];
      requires = [ "network.target" ];
      after = [ "network.target" "multi-user.target" ];

      serviceConfig = {
        Type = "simple";
        Restart = "always";
        EnvironmentFile = config.my.vault.secrets.fup-environment.path;
        ExecStart = "${pkg}/bin/fup serve --config=/etc/fup.yaml";
        User = "fup";
      };
    };
    environment.etc."fup.yaml".source = config.my.vault.secrets.fup-config.path;
    my.vault.secrets.fup-config = {
      reloadOrRestartUnits = ["fup.service"];
      group = "fup";
      template = ''
        {{ with secret "kv/apps/fup" }}
        {{ .Data.data.config }}
        {{ end }}
      '';
    };
    my.vault.secrets.fup-environment = {
      reloadOrRestartUnits = ["fup.service"];
      group = "fup";
      template = ''
        {{ with secret "kv/apps/fup" }}
        {{ .Data.data.environment }}
        {{ end }}
      '';
    };
  };
}