{ config, pkgs, ... }:
let
  cfg = {
    stateDir = "/var/lib/qbittorrent";
    downloadDir = "/var/videos/"; # TODO support other Media Types
    port = 8081;
    user = "qbittorrent";
  };
in
{
  imports = [
    ./exporter.nix
  ];
  age.secrets.mullvad.file = ../../../../secrets/nuc/mullvad.age;
  age.secrets.airvpn-private.file = ../../../../secrets/nuc/airvpn/private.age;
  age.secrets.airvpn-psk.file = ../../../../secrets/nuc/airvpn/psk.age;
  environment.etc."netns/torrent/resolv.conf".text = ''
    nameserver 9.9.9.9
  '';

  systemd.services."netns@" = {
    description = "%I network namespace";
    before = [ "network.target" ];
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
      ExecStart = "${pkgs.iproute2}/bin/ip netns add %I";
      ExecStartPost = "${pkgs.iproute2}/bin/ip netns exec %I ${pkgs.iproute2}/bin/ip link set dev lo up";
      ExecStop = "${pkgs.iproute2}/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.useNetworkd = false;
  # 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" ];
  # };
  networking.wireguard.interfaces."wg1-airvpn" = {
    privateKeyFile = config.age.secrets.airvpn-private.path;
    ips = [ " 10.146.65.170/32" "fd7d:76ee:e68f:a993:366:82ed:bc88:b04a/128" ];
    peers = [
      {
        publicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
        presharedKeyFile = config.age.secrets.airvpn-psk.path;
        allowedIPs = [ "0.0.0.0/0" "::/0" ];
        endpoint = "europe3.vpn.airdns.org:1637";
      }
    ];
    interfaceNamespace = "torrent";
  };
  systemd.services."wireguard-wg1-airvpn" = {
    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} - -"
  ];
}

