{ config, pkgs, lib, host, hostName, ... }:
let
  inherit (config.networking) domain;
  inherit (config.users) users;
  srv = "radicle";
  radicle = config.services.radicle;
  seed = "${srv}-${hostName}.${domain}";
in
{
  services.radicle = {
    enable = true;
    privateKeyFile = "key:${radicle/key.cred}";
    publicKey = radicle/key.pub;
    #package = pkgs.radicle-node;
    node = { };
    # FIXME: because radicle-node from the heartwood's flake.nix does not include rad
    # Should be re-enabled once radicle-node comes from Nixpkgs
    checkConfig = false;
    httpd = {
      enable = true;
      package = pkgs.radicle-httpd;
      nginx = {
        serverName = seed;
        forceSSL = true;
        enableACME = false;
        useACMEHost = domain;
        extraConfig = ''
          access_log off;
          error_log  /var/log/nginx/${domain}/${srv}-${hostName}/error.log warn;
        '';
      };
    };
    settings = {
      preferredSeeds = [
        "z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776"
        #"z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo@ash.radicle.garden:8776"
      ];
      publicExplorer = "https://${srv}.${domain}/nodes/$host/$rid$path";
      node = {
        policy = "block";
        scope = "all";
        # Relaying produces a constant network stream!
        relay = "never";
        # Make this a public node
        #externalAddresses = [
        #  "${seed}:${toString radicle.node.listenPort}"
        #  #"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion:${toString radicle.node.listenPort}"
        #];
        peers = {
          type = "dynamic";
          target = 0;
        };
        limits = {
          routingMaxSize = 1000;
          routingMaxAge = 1 * 7 * 24 * 60 * 60; # 1 week
          gossipMaxAge = 1 * 7 * 24 * 60 * 60; # 1 week
          fetchConcurrency = 1;
          maxOpenFiles = 4096;
          rate = {
            inbound = {
              fillRate = 1;
              capacity = 1;
            };
            outbound = {
              fillRate = 1;
              capacity = 1;
            };
          };
          connection = {
            inbound = 16;
            outbound = 8;
          };
        };
        workers = host.CPUs;
        /*
        onion = {
          mode = "proxy";
          address = "127.0.0.1:9050";
        };
        */
      };
      web = {
        pinned = {
          # Pinned repositories must be `rad clone`-d before.
          repositories = [
            "rad:z2364hmzZUAGy1nKdSFa1gLSoUE2M" # literate-phylomemy
            "rad:z3795BqJN8hSMGkyAUr8hHviEEi2H" # logic
            "rad:z4NtwMC1GmUuCRLngaZrVrSZLmUvh" # symantic-base
          ];
        };
      };
    };
  };
  systemd.services.radicle-node = {
    environment.RUST_LOG = "debug";
    serviceConfig = {
      CPUAccounting = true;
      CPUWeight = "idle";
      #CPUQuota = "60%";
      MemoryAccounting = true;
      MemoryHigh = "500M";
      MemoryMax = "600M";
      CPUSchedulingPolicy = "idle";
      IOSchedulingClass = "idle";
      # 0: high priority, 7: low priority
      IOSchedulingPriority = 3;
      Nice = 15;
    };
  };
  services.sanoid.datasets."rpool/var/lib/${srv}" = {
    use_template = [ "snap" ];
    hourly = 0;
    daily = 7;
    monthly = 0;
    recursive = true;
  };
  environment.systemPackages = [
    pkgs.radicle-node
  ];

  networking.nftables.ruleset = ''
    table inet filter {
      chain input-net {
        tcp dport ${toString radicle.node.listenPort} counter accept comment "radicle-node"
      }
      chain input-neb-sourcephile {
        tcp dport ${toString radicle.node.listenPort} counter accept comment "radicle-node"
      }
      chain output-net {
        skuid ${users.radicle.name} meta l4proto tcp counter accept comment "radicle-node"
      }
    }
  '';

  services.nginx.virtualHosts."${srv}-explorer.${domain}" = {
    serverAliases = [ "${srv}.${domain}" ];
    forceSSL = true;
    useACMEHost = domain;
    extraConfig = ''
      access_log off;
      error_log  /var/log/nginx/${domain}/${srv}-explorer/error.log warn;
    '';
    locations."/" = {
      extraConfig = ''
        try_files $uri $uri/ /index.html;
      '';
      index = "index.html";
      root = pkgs.radicle-explorer.overrideAttrs (previousAttrs: {
        postPatch = (previousAttrs.postPatch or "") + ''
          cp ${pkgs.writeText "local.json" ''
            {
              "nodes": {
                "fallbackPublicExplorer": "https://app.radicle.xyz/nodes/$host/$rid$path",
                "defaultHttpdPort": 443,
                "defaultLocalHttpdPort": 8080,
                "defaultHttpdHostname": "localhost",
                "defaultHttpdScheme": "https",
                "defaultNodePort": 8776,
                "pinned": [
                  {
                    "baseUrl": {
                      "hostname": "${seed}",
                      "port": 443,
                      "scheme": "https"
                    }
                  }
                ]
              },
              "supportWebsite": "https://radicle.zulipchat.com",
              "reactions": ["👍", "👎", "😄", "🙁", "👀"],
              "fallbackPreferredSeed": {
                "hostname": "${seed}",
                "port": 443,
                "scheme": "https"
              }
            }
          ''} config/local.json
        '';
      });
    };
  };
  systemd.services.nginx.serviceConfig.LogsDirectory = lib.mkForce [
    "nginx/${domain}/${srv}-${hostName}"
    "nginx/${domain}/${srv}-explorer"
  ];

}