{ zentralwerk, config, lib, ... }:

let
  defaultGateways = {
    serv = "serv-gw";
    c3d2 = "c3d2-gw3";
    pub = "pub-gw";
    flpk = "flpk-gw";
  };

  inherit (config.networking) hostName;
  inherit (config.system.build.skyflake-deployment) user repo vmName;
  inherit (config.deployment) networks;

  generateMacAddress = net:
    let
      hash = builtins.hashString "md5" "1-${net}-${hostName}";
      c = off: builtins.substring off 2 hash;
    in
      "${builtins.substring 0 1 hash}2:${c 2}:${c 4}:${c 6}:${c 8}:${c 10}";

  withoutLeadingSlash = s:
    let s' = lib.removePrefix "/" s; in
    if s' == s
    then s
    else withoutLeadingSlash s';

  writableStoreOverlayImage = "/var/tmp/${user}-${repo}-${vmName}-overlay.img";

in
{
  microvm = {
    inherit (config.deployment) mem vcpu hypervisor;

    preStart = ''
      # Discard old writable store overlay
      rm -f "${writableStoreOverlayImage}"
    '';

    shares =
      [ {
        proto = "virtiofs";
        tag = "ro-store";
        source = "/nix/store";
        mountPoint = "/nix/.ro-store";
      } ]
      ++
      map (mountPoint: {
        proto = "virtiofs";
        tag = builtins.replaceStrings [ "/" ] [ "-" ] (
          withoutLeadingSlash mountPoint
        );
        source = "/storage/cephfs/microvms/${user}/${repo}/${vmName}/${withoutLeadingSlash mountPoint}";
        inherit mountPoint;
      }) config.deployment.persistedShares
      ++
      map ({ source, mountPoint }: {
        proto = "virtiofs";
        tag = builtins.replaceStrings [ "/" ] [ "-" ] (
          withoutLeadingSlash mountPoint
        );
        inherit mountPoint source;
      }) config.deployment.extraShares;
    volumes = [ {
      image = writableStoreOverlayImage;
      mountPoint = config.microvm.writableStoreOverlay;
      size = 8 * 1024;
    } ];
    writableStoreOverlay = "/nix/.rw-store";

    interfaces = map (net: {
      type = "tap";
      id = builtins.substring 0 15 "${net}-${hostName}";
      mac = generateMacAddress net;
    }) config.deployment.networks;
  };

  skyflake = {
    nomadJob = {
      affinities = lib.optionals config.deployment.needForSpeed (builtins.genList (i: {
        attribute = "\${meta.c3d2.cpuSpeed}";
        operator = ">=";
        value = toString (i + 1);
        weight = 10 + i;
      }) 10);
    };
  };

  networking = {
    useDHCP = false;
    dhcpcd.enable = false;
    useNetworkd = true;
  };

  systemd.network = {
    links = builtins.foldl' (links: net: links // {
      "30-${net}" = {
        # enable = true;
        matchConfig.MACAddress = generateMacAddress net;
        # rename interface to net name
        linkConfig.Name = net;
      };
    }) {} networks;

    networks = builtins.foldl' (networks: net: networks // {
      "30-${net}" =
        let
          zwNet = zentralwerk.lib.config.site.net.${net};
          addresses =
            lib.optional (zwNet.hosts4 ? ${hostName}) "${zwNet.hosts4.${hostName}}/${toString zwNet.subnet4Len}"
            ++
            map (hosts6: "${hosts6.${hostName}}/64") (
builtins.filter (hosts6: hosts6 ? ${hostName}) (
  builtins.attrValues zwNet.hosts6
)
);
        in {
          matchConfig.MACAddress = generateMacAddress net;
          addresses = map (Address: {
            addressConfig = { inherit Address; };
          }) addresses;
          gateway = lib.mkIf (defaultGateways ? ${net}) (
            let
              gw = defaultGateways.${net};
            in
              [ zwNet.hosts4.${gw} ]
              ++ map (hosts6: hosts6.${gw}) (
                builtins.filter (hosts6: hosts6 ? ${gw}) (
                  builtins.attrValues zwNet.hosts6
                )
              )
          );
        };
    }) {} networks;
  };

  # nix-gc breaks writable store overlays, devastating running
  # MicroVMs
  nix.gc.automatic = false;
}
