{ config, lib, pkgs, ... }:
let
  cfg = config.selfprivacy;
  dnsCredentialsTemplates = {
    DIGITALOCEAN = "DO_AUTH_TOKEN=$TOKEN";
    CLOUDFLARE = ''
      CF_API_KEY=$TOKEN
      CLOUDFLARE_DNS_API_TOKEN=$TOKEN
      CLOUDFLARE_ZONE_API_TOKEN=$TOKEN
      CLOUDFLARE_POLLING_INTERVAL=30
    '';
    DESEC = ''
      DESEC_TOKEN=$TOKEN
      DESEC_POLLING_INTERVAL=30
      DESEC_PROPAGATION_TIMEOUT=180
      DESEC_TTL=3600
    '';
  };
  dnsCredentialsTemplate = dnsCredentialsTemplates.${cfg.dns.provider};
  acme-env-filepath = "/var/lib/selfprivacy/acme-env";
  secrets-filepath = "/etc/selfprivacy/secrets.json";
  dnsPropagationCheckExceptions = [ "DIGITALOCEAN" "DESEC" ];
in
{
  users.groups.acmereceivers.members = [ "nginx" ];
  security.acme = {
    acceptTerms = true;
    defaults = {
      email = "${cfg.username}@${cfg.domain}";
      server = if cfg.dns.useStagingACME then "https://acme-staging-v02.api.letsencrypt.org/directory" else "https://acme-v02.api.letsencrypt.org/directory";
      reloadServices = [ "nginx" ];
    };
    certs = {
      "${cfg.domain}" = {
        domain = "*.${cfg.domain}";
        group = "acmereceivers";
        dnsProvider = lib.strings.toLower cfg.dns.provider;
        credentialsFile = acme-env-filepath;
        dnsPropagationCheck =
          ! (lib.elem cfg.dns.provider dnsPropagationCheckExceptions);
      };
      "root-${cfg.domain}" = {
        domain = cfg.domain;
        group = "acmereceivers";
        webroot = "/var/lib/acme/acme-challenge";
      };
    };
  };
  systemd.services.acme-secrets = {
    before = [ "acme-${cfg.domain}.service" ];
    requiredBy = [ "acme-${cfg.domain}.service" ];
    serviceConfig.Type = "oneshot";
    path = with pkgs; [ coreutils jq ];
    script = ''
      set -o nounset

      TOKEN="$(jq -re '.dns.apiKey' ${secrets-filepath})"
      filecontents=$(cat <<- EOF
      ${dnsCredentialsTemplate}
      EOF
      )

      install -m 0440 -o root -g acmereceivers -DT \
      <(printf "%s\n" "$filecontents") ${acme-env-filepath}
    '';
  };
}