{ config, lib, pkgs, sources, ... }:

let
  inherit (lib) mapAttrs' mkEnableOption mkIf mkOption nameValuePair types;

  package = import sources.linkal { inherit pkgs; };

  cfg = config.dgn-linkal;

  jsonFormat = pkgs.formats.json { };
in {
  options.dgn-linkal = {
    enable = mkEnableOption "the linkal server.";

    package = mkOption {
      type = types.package;
      default = package.overrideAttrs (_: { buildInputs = [ ]; });
    };

    domain = mkOption { type = types.str; };

    calendarGroups = mkOption {
      type = let inherit (types) attrsOf port submodule;
      in attrsOf (submodule {
        options = {
          port = mkOption { type = port; };
          calendars = mkOption { inherit (jsonFormat) type; };
        };
      });
      default = { };
    };
  };

  config = mkIf cfg.enable {
    systemd.services = mapAttrs' (name:
      { port, calendars }:
      nameValuePair "linkal-${name}" {
        description = "Linkal - ${name}";
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          Type = "simple";
          ExecStart = "${cfg.package}/bin/linkal --port ${
              builtins.toString port
            } --calendar-file ${
              jsonFormat.generate "linkal-${name}.json" { inherit calendars; }
            }";
        };
      }) cfg.calendarGroups;

    # Configure bind for DNS certificate validation on *.cal.dgnum.eu.
    # services.bind = {
    #   enable = true;
    #   ipv4Only = true;
    #   extraConfig = ''
    #     include "${config.age.secrets."named-bind_dnskeys_conf".path}";
    #   '';
    #
    #   zones = [rec {
    #     name = "cal.dgnum.eu";
    #     file = "/var/db/bind/${name}";
    #     master = true;
    #     extraConfig = ''
    #       allow-update { key "rfc2136key.cal.dgnum.eu"; };
    #     '';
    #   }];
    # };
    #
    # networking.firewall = {
    #   allowedTCPPorts = [ 53 ];
    #   allowedUDPPorts = [ 53 ];
    # };
    #
    # dgn-secrets.options = [{ named-bind_dnskeys_conf.owner = "named"; }];
    #
    # # Configure ACME for DNS certificate validation
    # security.acme = {
    #   acceptTerms = true;
    #   defaults = {
    #     dnsProvider = "rfc2136";
    #     credentialsFile = config.age.secrets."acme-certs_secret".path;
    #     dnsPropagationCheck = false;
    #   };
    # };

    services.nginx = {
      enable = true;

      virtualHosts = mapAttrs' (name:
        { port, ... }:
        nameValuePair "${name}.${cfg.domain}" {
          enableACME = true;
          # acmeRoot = null; # Use DNS-01 validation
          forceSSL = true;

          locations."/".proxyPass =
            "http://127.0.0.1:${builtins.toString port}/";
        }) cfg.calendarGroups;
    };
  };
}