{ 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 = 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;
          '';
        };
      };
    };

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

    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 = 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 }}
      '';
    };
  };
}