{ config, pkgs, ... }:
let
  cfg = {
    stateDir = "/var/lib/qbittorrent";
    downloadDir = "/var/videos/"; # TODO support other Media Types
    port = 8081;
    user = "qbittorrent";
  };
in
{
  age.secrets.mullvad.file = ../../../../secrets/nuc/mullvad.age;
  environment.etc."netns/torrent/resolv.conf".text = ''
    nameserver 10.64.0.1
  '';

  systemd.services."netns@" = {
    description = "%I network namespace";
    before = [ "network.target" ];
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
      ExecStart = "${pkgs.iproute}/bin/ip netns add %I";
      ExecStartPost = "${pkgs.iproute2}/bin/ip netns exec %I ${pkgs.iproute2}/bin/ip link set dev lo up";
      ExecStop = "${pkgs.iproute}/bin/ip netns del %I";
    };
  };

  systemd.services."qbittorrent-portforward@" = {
    description = "%I network namespace port mapping";
    requires = [ "netns@%i.service" ];
    after = [ "netns@%i.service" ];
    # wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      Restart = "on-failure";
      TimeoutStopSec = 300;
      ExecStart = ''${pkgs.socat}/bin/socat tcp-listen:${toString cfg.port},fork,reuseaddr exec:'${pkgs.iproute2}/bin/ip netns exec %I ${pkgs.socat}/bin/socat STDIO "tcp-connect:127.0.0.1:${toString cfg.port}"',nofork'';
      # ExecStart = [
      #   "${pkgs.socat}/bin/socat tcp-listen:%j,fork,reuseaddr"
      #   ''${pkgs.iproute2}/bin/ip netns exec %I ${pkgs.socat}/bin/socat STDIO "tcp-connect:127.0.0.1:%j",nofork''
      # ];
    };
  };

  # scripted wireguard since systemd-networkd doesn't support netns yet
  networking.wireguard.interfaces."wg0-mullvad" = {
    # Funny Mole
    privateKeyFile = config.age.secrets.mullvad.path;
    ips = [ "10.67.237.93/32" ];
    peers = [
      {
        publicKey = "QEVIaIycN8p5twXCuZeQTEj9utozakw/MU8H6+/whls=";
        allowedIPs = [ "0.0.0.0/0" ];
        endpoint = "138.199.34.129:51820";
      }
    ];
    interfaceNamespace = "torrent";
  };
  systemd.services."wireguard-wg0-mullvad" = {
    requires = [ "netns@torrent.service" ];
  };

  users.users.${cfg.user} = {
    group = cfg.user;
    home = cfg.stateDir;
    isSystemUser = true;
    extraGroups = [ "media" ];
  };
  users.groups.${cfg.user} = { };
  systemd.services."qbittorrent" = {
    description = "qBittorrent Service";
    bindsTo = [ "netns@torrent.service" ];
    after = [ "netns@torrent.service" ];
    requires = [ "qbittorrent-portforward@torrent.service" ];
    wantedBy = [ "multi-user.target" ];

    serviceConfig = {
      User = cfg.user;
      Group = cfg.user;
      Restart = "always";

      # PrivateNetwork = true;
      NetworkNamespacePath = "/var/run/netns/torrent";

      ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox --profile=${cfg.stateDir} --webui-port=${toString cfg.port}";

      # Increase number of open file descriptors (default: 1024)
      # LimitNOFILE = 65536;

      # Avoid using nscd (leaks dns)
      InaccessiblePaths = [ "/run/nscd" ];
      BindReadOnlyPaths = [
        "/etc/netns/torrent/resolv.conf:/etc/resolv.conf"
      ];

      # systemd-analyze --no-pager security qbittorrent.service
      CapabilityBoundingSet = null;
      PrivateDevices = true;
      PrivateTmp = true;
      PrivateUsers = true;
      ProtectHome = true;
      RestrictNamespaces = true;
      SystemCallFilter = "@system-service";
    };
  };
  networking.firewall.allowedTCPPorts = [ cfg.port ];
  systemd.tmpfiles.rules = [
    # ensure downloads directory is created, set permissions
    "d ${cfg.stateDir} - ${cfg.user} ${cfg.user} - -"
    "d ${cfg.stateDir}/qBittorrent - ${cfg.user} ${cfg.user} - -"
  ];
}