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

let
  inherit (depot.ops) secrets;
  sock = "/run/fup.sock";
  pkg = depot.web.fup;

  format = pkgs.formats.yaml {};
  fupConfig = format.generate "fup.yaml" secrets.fup.config;
in
{
  options = with lib; {
    my.fup.listen = lib.mkOption {
      type = with types; listOf str;
      default = [ "127.0.0.1" "[::1]" ];
    };
  };

  config = let
    nginxListen = (map (addr: {
      inherit addr;
      port = 80;
      ssl = false;
    }) config.my.fup.listen) ++ (map (addr: {
      inherit addr;
      port = 443;
      ssl = true;
    }) config.my.fup.listen);
  in {
    my.vault.acmeCertificates."p.lukegb.com" = {
      hostnames = [ "p.lukegb.com" ];
      nginxVirtualHosts = [ "p.lukegb.com" ];
    };
    services.nginx = {
      enable = lib.mkDefault true;
      virtualHosts."p.lukegb.com" = {
        listen = nginxListen;
        forceSSL = true;
        locations."/" = {
          proxyPass = "http://unix:${sock}";
          extraConfig = ''
            proxy_redirect off;
            client_max_body_size 0;
            proxy_buffering off;
          '';
        };
      };
    };

    systemd.sockets.fup = {
      listenStreams = [ sock ];
      wantedBy = [ "sockets.target" ];
      socketConfig = {
        SocketUser = config.services.nginx.user;
        SocketGroup = config.services.nginx.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 = secrets.fup.environment;
        ExecStart = "${pkg}/bin/fup serve --config=${fupConfig}";
        DynamicUser = true;
      };
    };
  };
}