{ lib, callPackage, runCommand, writeTextDir, symlinkJoin, makeBubblewrap,
  fetchFromGitHub, weechat, pass }:

with lib;
let
  flattenAttrs = set:
    let recurse = k: v:
      if isAttrs v
      then mapAttrsToList (k': recurse "${k}.${k'}") v
      else nameValuePair k v;
    in listToAttrs (flatten (mapAttrsToList recurse set));
  
  mkValueString = v:
    if isInt v then toString v
    else if isString v then "\"${v}\""
    else if true == v then "on"
    else if false == v then "off"
    else abort "unsupported value type: ${builtins.typeOf v}";

  mkKeyValue = k: v:
    if isAttrs v then concatStringsSep "\n" (mapAttrsToList (k': mkKeyValue "${k}.${k'}") (flattenAttrs v))
    else "${k} = ${mkValueString v}";

  toConfigFile = name: attrs:
    writeTextDir "${name}.conf" (generators.toINI { inherit mkKeyValue; } attrs);

  scripts = fetchFromGitHub {
    owner = "weechat";
    repo = "scripts";
    rev = "712b6773d1ae49771b5030341433fb55dd89a6d6";
    sha256 = "17bkgdvavwz4y7wica9vfhaygibwwppn6f09cbhh1vad68a1s4rs";
  };

  scriptsDir = runCommand "scripts" {} ''
    mkdir -p $out/python/autoload
    ln -s \
      ${scripts}/python/go.py \
      ${scripts}/python/autosort.py \
      ${scripts}/python/prism.py \
      $out/python/autoload/

    mkdir -p $out/perl/autoload
    ln -s \
      ${scripts}/perl/colorize_lines.pl \
      ${scripts}/perl/notify_send.pl \
      $out/perl/autoload/
  '';

  config = import ./config.nix { inherit lib; };
  homeDir = symlinkJoin {
    name = "weechat-home";
    paths = [ scriptsDir ] ++ (mapAttrsToList toConfigFile config);
  };
in makeBubblewrap {
  name = "irc";
  argv = "${weechat}/bin/weechat";

  env.HOME = "/jail";
  env.ZNC_PASSWORD = "$(${pass}/bin/pass tilpner/znc.tilpner.com/till)";

  rules = p: with p; [
    base
    (tmpfs "/jail")
  ];

  preRunInside = ''
    cp -r ${homeDir} /jail/.weechat
    chmod -R 700 /jail
  '';
} // { passthru = { inherit homeDir; }; }