{ config, pkgs, lib, ... }:
let
  mkDomain = subname: "${subname}.${config.networking.fqdn}";
in
{
  # TODO: make these into nixos options
  _module.args.mkDomain = mkDomain;
  _module.args.allSubdomains = lib.pipe config.services.nginx.virtualHosts [
    #(lib.mapAttrsToList (domain: vhost: [ domain ] ++ vhost.serverAliases))
    (lib.mapAttrsToList (domain: vhost: [ domain ]))
    lib.flatten
    (builtins.filter (domain: domain != "" && domain != "_"))
    (lib.sort (x: y: x<y))
  ];

  security.acme.acceptTerms = true;
  security.acme.defaults.email = "pbsds+acme@hotmail.com"; # TODO: parametrize per host
  #security.acme.defaults.renewInterval = "daily";
  #security.acme.defaults.reloadServices

  # https://www.xf.is/2020/06/30/list-of-free-acme-ssl-providers/
  #security.acme.defaults.server = "https://acme-v02.api.letsencrypt.org/directory" # default
  #security.acme.defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory"; # STAGING
  #security.acme.defaults.server = "https://api.buypass.com/acme/directory"; # no wildcards, rate limit: 20 domains/week, 5 duplicate certs / week
  #security.acme.defaults.server = "https://api.test4.buypass.no/acme/directory"; # STAGING. no wildcards, rate limit: 20 domains/week, 5 duplicate certs / week

  # DNS-based ACME:
  # - https://go-acme.github.io/lego/dns/domeneshop/
  # - https://nixos.org/manual/nixos/stable/index.html#module-security-acme-config-dns-with-vhosts
  #security.acme.defaults.dnsProvider = "domeneshop";
  #security.acme.defaults.credentialsFile = "/var/lib/secrets/domeneshop.key"; # TODO: this file must be made by hand, containing env variables.

  services.nginx.enable = true;
  networking.firewall.allowedTCPPorts = [ 80 443 ];

  # TODO:
  #services.nginx.commonHttpConfig = ''
  #  proxy_hide_header X-Frame-Options;
  #'';
  # TODO: Somehow distribute and add this to all location."/".extraConfig
  #default = {
  #  #useACMEHost = config.networking.fqdn;
  #  forceSSL = true; # addSSL = true;
  #  enableACME = true; #useACMEHost = acmeDomain;
  #}
  # TODO: Somehow distribute and add this to all location."/".extraConfig
  #commonProxySettings = ''
  #  proxy_set_header Host $host;
  #  proxy_set_header X-Real-IP $remote_addr;
  #  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  #  proxy_set_header X-Forwarded-Proto $scheme;
  #  proxy_set_header X-Forwarded-Host $host;
  #  proxy_set_header X-Forwarded-Server $host;
  #'';

  services.nginx.recommendedGzipSettings = true;
  services.nginx.recommendedOptimisation = true;
  services.nginx.recommendedProxySettings = true;
  services.nginx.recommendedTlsSettings = true;

  # nginx return 444 for all nonexistent virtualhosts
  services.nginx.virtualHosts."_" = {
    addSSL = true;
    sslCertificate = "${pkgs.path}/nixos/tests/common/acme/server/acme.test.cert.pem";
    sslCertificateKey = "${pkgs.path}/nixos/tests/common/acme/server/acme.test.key.pem";
    extraConfig = "return 444;";
  };

  /** /
  services.nginx.virtualHosts."" = {
    default = true;
    forceSSL = false;
    enableACME = false;
    root = pkgs.writeTextDir "index.html" ''
      <!DOCTYPE html>
      no
    '';
  };
  /**/

  # Website tunnel
  # TODO: remove
  /** /
  services.nginx.virtualHosts.${config.networking.fqdn} = {
    forceSSL = true; # addSSL = true;
    enableACME = true;
    #acmeRoot = null; # use DNS
    default = true;
    serverAliases = map mkDomain [
      "www"
      #"*" # requires DNS ACME
    ];
    # The alternative to ^ is: config.security.acme.certs."${acmeDomain}".extraDomainNames = [ (mkDomain "foo") ];
    # TODO: 'nox' alias for everything
    locations."/" = {
      proxyPass = "http://pbuntu.pbsds.net";
      proxyWebsockets = true;
    };
  };
  #services.nginx.virtualHosts.${mkDomain "www"} = {
  #  addSSL = true;
  #  useACMEHost = acmeDomain; #enableACME = true;
  #  locations."/" = {
  #    proxyPass = "http://pbuntu.pbsds.net";
  #    proxyWebsockets = true;
  #  };
  #};
  /**/


}