{ config, lib, ... }:

let
  rootDomain = config.networking.domain;
  ports = import ./Ports.nix;
in
{
  networking.firewall = {
    allowedTCPPorts = [
      ports.ssh
      ports.git
      ports.http
      ports.https
      ports.sabten
      ports.gemini
      ports.radicale
      ports.znc
    ];
  };

  services = {
    radicale = {
      enable = true;
      settings = {
        server = {
          hosts = [
            "0.0.0.0:${toString ports.radicale}"
            "[::]:${toString ports.radicale}"
          ];
        };
        auth = {
          type = "htpasswd";
          htpasswd_filename = "/etc/radicale/users";
          htpasswd_encryption = "plain";
        };
      };
    };
    gmnisrv = {
      enable = true;
      settings = {
        listen = "0.0.0.0:${toString ports.gemini} [::]:${toString ports.gemini}";
        ":tls" = { store = "/var/lib/gmnisrv"; };
        "bsima.me" = {
          "root" = "/var/web/ben";
        };
        "simatime.com" = {
          "root" = "/var/web/simatime.com";
          "cgi" = "on";
        };
      };
    };

    nginx = {
      enable = true;
      recommendedGzipSettings = true;
      recommendedOptimisation = true;
      recommendedProxySettings = true;
      recommendedTlsSettings = true;
      statusPage = true;

      user = "nginx";
      group = "nginx";

      virtualHosts = {
        ${rootDomain} = {
          forceSSL = true;
          enableACME = true;
          locations = {
            "/" = {
              root = "/var/web/simatime.com";
              extraConfig = ''
                autoindex on;
              '';
            };
            # serve /~$USER paths
            "~ ^/~(.+?)(/.*)?$" = {
              alias = "/var/web/$1$2";
              index = "index.html index.htm";
              extraConfig = ''
                autoindex on;
              '';
            };
          };
          cgit = {
            enable = true;
            location = "/git";
            virtual-root = "/git";
            css = "/git/cgit.css";
            logo = "/git/cgit.png";
            root-title = "ben's git repos";
            root-desc = "building";
            enable-git-config = 1;
            clone-url = lib.strings.concatStringsSep " " [
              "https://$HTTP_HOST/git/$CGIT_REPO_URL"
              "git://$HTTP_HOST/$CGIT_REPO_URL"
              "git@$HTTP_HOST:$CGIT_REPO_URL"
            ];
            include = [
              # these depend on order, scan-path must come last
              (builtins.toFile "cgitrc" ''
                strict-export=git-daemon-export-ok
                scan-path=/srv/git/repositories
              '')
            ];
          };
        };

        "bsima.me" = {
          locations."/" = {
            root = "/var/web/ben";
            index = "index.html index.htm";
            extraConfig = ''
              autoindex on;
            '';
          };
          serverAliases = [ "www.bsima.me" ];
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "hoogle.${rootDomain}" = {
          locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.hoogle}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "tv.${rootDomain}" = {
          locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.jellyfin}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "cal.${rootDomain}" = {
          locations."/".proxyPass = "http://localhost:${toString ports.radicale}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "devalloc.io" = {
          forceSSL = true;
          useACMEHost = rootDomain;
          globalRedirect = "dragons.dev";
        };

        "dragons.dev" = {
          locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.dragons}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "dandel-rovbur.${rootDomain}" = {
          locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.dandel-rovbur}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "sabten.${rootDomain}" = {
          locations."/".proxyPass = "http://localhost:${toString ports.sabten}";
          forceSSL = true;
          useACMEHost = rootDomain;
        };

        "notebook.simatime.com" = {
          forceSSL = true;
          useACMEHost = rootDomain;
          locations = {
            "/" = {
              proxyPass = "http://${ports.bensIp}:${toString ports.jupyter}";
              proxyWebsockets = true;
              extraConfig = ''
                proxy_buffering off;
                proxy_read_timeout 86400;
              '';
            };
            "/(api/kernels/[^/]+/channels|terminals/websocket)/" = {
              proxyPass = "http://${ports.bensIp}:${toString ports.jupyter}";
              proxyWebsockets = true;
            };
          };
        };

      };
    };
  };

  # This must contain all of the other domains we host
  security.acme.certs.${rootDomain}.extraDomainNames = [
    "bsima.me" "www.bsima.me"
    "dragons.dev" "devalloc.io"
  ] ++ map (sub: "${sub}.${rootDomain}") [
    "tv"
    "matrix"
    "chat"
    "hoogle"
    "dandel-rovbur"
    "sabten"
    "cal"
    "notebook"
  ];
}