{ config, pkgs, lib, inputs, ... }:
let
  cfg = config.services.domeneshop-updater;
in
{
  # auto domain update

  # TODO: ensure dns64 does not interfere with this

  options = with lib; {
    services.domeneshop-updater.targets = mkOption {
      type = with types; listOf str;
      example = [ config.networking.fqdn ];
    };
  };
  # don't run if local VM
  config = lib.mkIf (cfg.targets != [] && !config.virtualisation.isVmVariant) {

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

    sops.secrets."domeneshop/token".sopsFile = "${inputs.self}/secrets/dns.yaml";
    sops.secrets."domeneshop/token".owner = "domeneshop";
    sops.secrets."domeneshop/token".group = "domeneshop";
    sops.secrets."domeneshop/secret".sopsFile = "${inputs.self}/secrets/dns.yaml";
    sops.secrets."domeneshop/secret".owner = "domeneshop";
    sops.secrets."domeneshop/secret".group = "domeneshop";

    systemd.services.domeneshop-updater = {
      description = "domene.shop dyndns domain updater";
      wantedBy = [ "multi-user.target" ];
      after = [ "network-online.target" ];
      wants = [ "network-online.target" ];
      serviceConfig = let
        prog = pkgs.writeShellApplication {
          name = "domeneshop-dyndns-updater.sh";
          runtimeInputs = with pkgs; [ curl iproute2 jq ];
          text = ''
            test -s /run/secrets/domeneshop/token || {
              >&2 echo "ERROR: /run/secrets/domeneshop/token not found!"
              exit 1
            }
            test -s /run/secrets/domeneshop/secret || {
              >&2 echo "ERROR: /run/secrets/domeneshop/secret not found!"
              exit 1
            }
            DOMENESHOP_TOKEN="$( cat /run/secrets/domeneshop/token)"
            DOMENESHOP_SECRET="$(cat /run/secrets/domeneshop/secret)"

            # get stable ipv6 addr, fallback to ipv4, fallback to curl default
            IF=$(
              ip -6 -json addr show scope global -temporary \
                | jq '.[]| select(.ifname|contains("docker")|not) | .addr_info[].local | select(.==null|not)' -r \
                | head -n1
            )
            if [[ -z "$IF" ]]; then
              IF=$(
                ip -4 -json addr show scope global -temporary \
                  | jq '.[]| select(.ifname|contains("docker")|not) | .addr_info[].local | select(.==null|not)' -r \
                  | head -n1
              )
            fi
            if [[ -n "$IF" ]]; then
              IF="--interface $IF"
            else
              IF=""
            fi

            # shellcheck disable=SC2086
            echo + curl $IF api.domeneshop.no...

            ${lib.concatMapStringsSep "\n" (target: ''
              # shellcheck disable=SC2086
              curl $IF https://"$DOMENESHOP_TOKEN":"$DOMENESHOP_SECRET"@api.domeneshop.no/v0/dyndns/update?hostname="${target}"
            '') cfg.targets}
          '';
        };
      in {
        User  = "domeneshop";
        Group = "domeneshop";
        #DynamicUser = true; # maybe re-enable when sops-nix is in place?
        ExecStart = "${prog}/bin/domeneshop-dyndns-updater.sh";
        PrivateTmp = true;
      };
    };
    systemd.timers.domeneshop-updater = let interval = "2h"; in {
      description = "Update domene.shop every ${interval}";
      wantedBy = [ "timers.target" ];
      timerConfig = {
        OnBootSec = "5m";
        OnUnitInactiveSec = interval;
        Unit = "domeneshop-updater.service";
      };
    };

  };
}
