{ lib }:

with lib; {
  irc.server_default = {
    capabilities = concatStringsSep "," [
      "account-notify" "away-notify" "cap-notify" "multi-prefix" "server-time"
      "znc.in/server-time-iso" "znc.in/self-message"
    ];
    nicks = "Foo,Bar,Quux";
    realname = "Quuux";
    ssl_verify = false;
    username = "bar";
  };

  irc.server = let
    zncNetwork = name: {
      addresses = "znc.bar.com";
      username = "bar/${name}";
      password = "\${env:ZNC_PASSWORD}";
      ssl = true;
      ssl_verify = false;
      autoconnect = false;
    }; 
    networks = [ "freenode" "mozilla" "oftc" ];
  in (listToAttrs (map (n: nameValuePair n (zncNetwork n)) networks));

  irc.look = {
    buffer_switch_autojoin = false;
    buffer_switch_join = false;
    server_buffer = "independent";
    smart_filter_delay = 60;
    temporary_servers = true;
    lag_reconnect = 0;
  };

  weechat = {
    notify.irc =
      let s = {
        freenode = [ "#nixos" ];
      };
      in mapAttrs (k: v: listToAttrs (map (v: nameValuePair v "message") v)) s;

    look = {
      prefix_align_max = 15;
      color_nick_offline = true;
      buffer_time_format = "\${color:252}%H\${color:245}%M\${color:240}%S";
      buffer_notify_default = "highlight";
    };

    plugin.autoload = "*,!aspell,!fifo,!relay,!xfer,!tcl,!guile";

    completion.nick_completer = " -";

    filter.irc_smart = "on;*;irc_smart_filter;*";
    filter.nixos_github = "on;*;nick_nixos_github+irc_join;*";

    color = {
      bar_more = "lightmagenta";
      chat = "default";
      chat_bg = "default";

      chat_nick_colors = concatStringsSep "," [
        "cyan" "magenta" "green" "brown" "lightcyan" "lightmagenta" "blue"
        "31" "35" "38" "40" "49" "70" "80" "99" "112" "138" "142" "148" "167"
        "169" "174" "176" "178" "184" "186" "210" "212" "215" "247"
      ];

      chat_highlight = "red";
      chat_highlight_bg = "black";

      chat_nick_offline = "!default";
      chat_nick_offline_highlight = "!default";
      chat_nick_offline_highlight_bg = "default";
    };

    bar = {
      buflist = {
        color_bg = "default";
        color_delim = "default";
        color_fg = "default";
        conditions = "";
        filling_left_right = "vertical";
        filling_top_bottom = "columns_vertical";
        hidden = false;
        items = "buflist";
        position = "right";
        priority = 0;
        separator = true;
        size = 0;
        size_max = 0;
        type = "root";
      };

      fset = {
        color_bg = "default";
        color_delim = "cyan";
        color_fg = "default";
        conditions = "\${buffer.full_name} == fset.fset";
        filling_left_right = "vertical";
        filling_top_bottom = "horizontal";
        hidden = false;
        items = "fset";
        position = "top";
        priority = 0;
        separator = true;
        size = 3;
        size_max = 3;
        type = "window";
      };

      input = {
        color_bg = "default";
        color_delim = "cyan";
        color_fg = "default";
        conditions = "";
        filling_left_right = "vertical";
        filling_top_bottom = "horizontal";
        hidden = false;
        items = "[input_prompt]+(away),[input_search],[input_paste],input_text";
        position = "bottom";
        priority = 1000;
        separator = false;
        size = 0;
        size_max = 0;
        type = "window";
      };

      isetbar = {
        color_bg = "default";
        color_delim = "cyan";
        color_fg = "default";
        conditions = "";
        filling_left_right = "vertical";
        filling_top_bottom = "horizontal";
        hidden = true;
        items = "isetbar_help";
        position = "top";
        priority = 0;
        separator = true;
        size = 3;
        size_max = 3;
        type = "window";
      };

      nicklist = {
        color_bg = "default";
        color_delim = "cyan";
        color_fg = "default";
        conditions = "\${nicklist}";
        filling_left_right = "vertical";
        filling_top_bottom = "columns_vertical";
        hidden = true;
        items = "buffer_nicklist";
        position = "right";
        priority = 200;
        separator = true;
        size = 0;
        size_max = 0;
        type = "window";
      };

      status = {
        color_bg = 0;
        color_delim = "cyan";
        color_fg = "default";
        conditions = "";
        filling_left_right = "vertical";
        filling_top_bottom = "horizontal";
        hidden = false;
        items = "[time],[buffer_last_number],[buffer_plugin],buffer_number+:+buffer_name+(buffer_modes)+{buffer_nicklist_count}+buffer_zoom+buffer_filter,scroll,[lag],[hotlist],completion";
        position = "bottom";
        priority = 500;
        separator = false;
        size = 1;
        size_max = 0;
        type = "window";
      };

      title = {
        color_bg = 0;
        color_delim = "cyan";
        color_fg = "default";
        conditions = "";
        filling_left_right = "vertical";
        filling_top_bottom = "horizontal";
        hidden = false;
        items = "buffer_title";
        position = "top";
        priority = 500;
        separator = false;
        size = 1;
        size_max = 0;
        type = "window";
      };
    };

    key = {
      "meta-#" = "/go";
      "meta-e" = "/go freenode.#nixos";

      "ctrl-?" = "/input delete_previous_char";
      "ctrl-A" = "/input insert \\x01";
      "ctrl-B" = "/input insert \\x02";
      "ctrl-C" = "/input insert \\x03";
      "ctrl-C_" = "/input insert \\x1F";
      "ctrl-Cb" = "/input insert \\x02";
      "ctrl-Cc" = "/input insert \\x03";
      "ctrl-Ci" = "/input insert \\x1D";
      "ctrl-Co" = "/input insert \\x0F";
      "ctrl-Cv" = "/input insert \\x16";
      "ctrl-D" = "/input delete_next_char";
      "ctrl-E" = "/input move_end_of_line";
      "ctrl-F" = "/input move_next_char";
      "ctrl-G" = "/input insert \\x0303\\x03\\x03; /input move_previous_char; /input move_previous_char";
      "ctrl-H" = "/input delete_previous_char";
      "ctrl-I" = "/input complete_next";
      "ctrl-J" = "/input return";
      "ctrl-K" = "/input delete_end_of_line";
      "ctrl-L" = "/window refresh";
      "ctrl-M" = "/input return";
      "ctrl-N" = "/buffer +1";
      "ctrl-P" = "/buffer -1";
      "ctrl-R" = "/input search_text_here";
      "ctrl-S" = "/input insert \\x0303$ \\x03\\x03; /input move_previous_char; /input move_previous_char";
      "ctrl-Sctrl-U" = "/input set_unread";
      "ctrl-T" = "/input transpose_chars";
      "ctrl-U" = "/input delete_beginning_of_line";
      "ctrl-W" = "/input delete_previous_word";
      "ctrl-X" = "/input switch_active_buffer";
      "ctrl-Y" = "/input clipboard_paste";
      "meta-meta-OP" = "/bar scroll buflist * b";
      "meta-meta-OQ" = "/bar scroll buflist * e";
      "meta-meta2-1~" = "/window scroll_top";
      "meta-meta2-23~" = "/bar scroll nicklist * b";
      "meta-meta2-24~" = "/bar scroll nicklist * e";
      "meta-meta2-4~" = "/window scroll_bottom";
      "meta-meta2-5~" = "/window scroll_up";
      "meta-meta2-6~" = "/window scroll_down";
      "meta-meta2-7~" = "/window scroll_top";
      "meta-meta2-8~" = "/window scroll_bottom";
      "meta-meta2-A" = "/buffer -1";
      "meta-meta2-B" = "/buffer +1";
      "meta-meta2-C" = "/buffer +1";
      "meta-meta2-D" = "/buffer -1";
      "meta--" = "/filter toggle @";
      "meta-/" = "/input jump_last_buffer_displayed";
      "meta-0" = "/buffer *10";
      "meta-1" = "/buffer *1";
      "meta-2" = "/buffer *2";
      "meta-3" = "/buffer *3";
      "meta-4" = "/buffer *4";
      "meta-5" = "/buffer *5";
      "meta-6" = "/buffer *6";
      "meta-7" = "/buffer *7";
      "meta-8" = "/buffer *8";
      "meta-9" = "/buffer *9";
      "meta-<" = "/input jump_previously_visited_buffer";
      "meta-=" = "/filter toggle";
      "meta->" = "/input jump_next_visited_buffer";
      "meta-M" = "/window scroll_up";
      "meta-N" = "/windows scroll_down";
      "meta-OA" = "/input history_global_previous";
      "meta-OB" = "/input history_global_next";
      "meta-OC" = "/input move_next_word";
      "meta-OD" = "/input move_previous_word";
      "meta-OF" = "/input move_end_of_line";
      "meta-OH" = "/input move_beginning_of_line";
      "meta-OP" = "/bar scroll buflist * -100%";
      "meta-OQ" = "/bar scroll buflist * +100%";
      "meta-Oa" = "/input history_global_previous";
      "meta-Ob" = "/input history_global_next";
      "meta-Oc" = "/input move_next_word";
      "meta-Od" = "/input move_previous_word";
      "meta2-15~" = "/buffer -1";
      "meta2-17~" = "/buffer +1";
      "meta2-18~" = "/window -1";
      "meta2-19~" = "/window +1";
      "meta2-1;3A" = "/buffer -1";
      "meta2-1;3B" = "/buffer +1";
      "meta2-1;3C" = "/buffer +1";
      "meta2-1;3D" = "/buffer -1";
      "meta2-1;3F" = "/window scroll_bottom";
      "meta2-1;3H" = "/window scroll_top";
      "meta2-1;5A" = "/input history_global_previous";
      "meta2-1;5B" = "/input history_global_next";
      "meta2-1;5C" = "/input move_next_word";
      "meta2-1;5D" = "/input move_previous_word";
      "meta2-1~" = "/input move_beginning_of_line";
      "meta2-200~" = "/input paste_start";
      "meta2-201~" = "/input paste_stop";
      "meta2-20~" = "/bar scroll title * -30%";
      "meta2-21~" = "/bar scroll title * +30%";
      "meta2-23;3~" = "/bar scroll nicklist * b";
      "meta2-23~" = "/bar scroll nicklist * -100%";
      "meta2-24;3~" = "/bar scroll nicklist * e";
      "meta2-24~" = "/bar scroll nicklist * +100%";
      "meta2-3~" = "/input delete_next_char";
      "meta2-4~" = "/input move_end_of_line";
      "meta2-5;3~" = "/window scroll_up";
      "meta2-5~" = "/window page_up";
      "meta2-6;3~" = "/window scroll_down";
      "meta2-6~" = "/window page_down";
      "meta2-7~" = "/input move_beginning_of_line";
      "meta2-8~" = "/input move_end_of_line";
      "meta2-A" = "/input history_previous";
      "meta2-B" = "/input history_next";
      "meta2-C" = "/input move_next_char";
      "meta2-D" = "/input move_previous_char";
      "meta2-F" = "/input move_end_of_line";
      "meta2-G" = "/window page_down";
      "meta2-H" = "/input move_beginning_of_line";
      "meta2-I" = "/window page_up";
      "meta2-Z" = "/input complete_previous";
      "meta2-[E" = "/buffer -1";
      "meta-_" = "/input redo";
      "meta-b" = "/input move_previous_word";
      "meta-d" = "/input delete_next_word";
      "meta-f" = "/input move_next_word";
      "meta-h" = "/input hotlist_clear";
      "meta-jmeta-f" = "/buffer -";
      "meta-jmeta-l" = "/buffer +";
      "meta-jmeta-r" = "/server raw";
      "meta-jmeta-s" = "/server jump";
      "meta-k" = "/input grab_key_command";
      "meta-l" = "/window bare";
      "meta-m" = "/window scroll_up";
      "meta-n" = "/window scroll_down";
      "meta-p" = "/window scroll_previous_highlight";
      "meta-return" = "/input return";
      "meta-u" = "/window scroll_unread";
      "meta-wmeta-meta2-A" = "/window up";
      "meta-wmeta-meta2-B" = "/window down";
      "meta-wmeta-meta2-C" = "/window right";
      "meta-wmeta-meta2-D" = "/window left";
      "meta-wmeta2-1;3A" = "/window up";
      "meta-wmeta2-1;3B" = "/window down";
      "meta-wmeta2-1;3C" = "/window right";
      "meta-wmeta2-1;3D" = "/window left";
      "meta-wmeta-b" = "/window balance";
      "meta-wmeta-s" = "/window swap";
      "meta-x" = "/input zoom_merged_buffer";
      "meta-z" = "/window zoom";
      "ctrl-_" = "/input undo";
    };

    key_search = {
      "ctrl-I" = "/input search_switch_where";
      "ctrl-J" = "/input search_stop_here";
      "ctrl-M" = "/input search_stop_here";
      "ctrl-Q" = "/input search_stop";
      "ctrl-R" = "/input search_switch_regex";
      "meta2-A" = "/input search_previous";
      "meta2-B" = "/input search_next";
      "meta-c" = "/input search_switch_case";
    };

    key_cursor = {
      "ctrl-J" = "/cursor stop";
      "ctrl-M" = "/cursor stop";
      "meta-meta2-A" = "/cursor move area_up";
      "meta-meta2-B" = "/cursor move area_down";
      "meta-meta2-C" = "/cursor move area_right";
      "meta-meta2-D" = "/cursor move area_left";
      "meta2-1;3A" = "/cursor move area_up";
      "meta2-1;3B" = "/cursor move area_down";
      "meta2-1;3C" = "/cursor move area_right";
      "meta2-1;3D" = "/cursor move area_left";
      "meta2-A" = "/cursor move up";
      "meta2-B" = "/cursor move down";
      "meta2-C" = "/cursor move right";
      "meta2-D" = "/cursor move left";
      "@chat:Q" = "hsignal:chat_quote_time_prefix_message;/cursor stop";
      "@chat:m" = "hsignal:chat_quote_message;/cursor stop";
      "@chat:q" = "hsignal:chat_quote_prefix_message;/cursor stop";
    };
  };

  alias.cmd = {
    alis = "/msg alis list $*";
    cs = "/msg ChanServ $*";
    ns = "/msg NickServ $*";
    znc = "/msg *status $*";

    spoiler = "/msg $channel 1,1$*";
    bhide = "/set weechat.bar.buffers.hidden toggle";
    voice = "/msg ChanServ voice $channel $*";
    devoice = "/msg ChanServ devoice $channel $*";
  };

  trigger.trigger = {
    input_command_color = {
      arguments = "input_text_display";
      command = "";
      conditions = "\${tg_string} =~ ^/($|[^/])";
      enabled = true;
      hook = "modifier";
      post_action = "none";
      regex = "#/(.+)#\${color:39}/\${color:74}\${re:1}#";
      return_code = "ok";
    };

    last_nick = {
      arguments = "irc.*;notify_message";
      command = "/buffer set localvar_set_last_nick \${tg_tag_nick}";
      conditions = "\${tg_displayed} && \${type} == channel && \${tg_tag_nick} != \${nick}";
      enabled = true;
      hook = "print";
      post_action = "none";
      regex = "";
      return_code = "ok";
    };

    complete_last_nick = {
      arguments = "/input complete_next";
      command = "/input insert \${last_nick}";
      conditions = "\${type} == channel && \${buffer.input_buffer_length} == 0 && \${last_nick}";
      enabled = true;
      hook = "command_run";
      post_action = "none";
      regex = "";
      return_code = "ok";
    };

    space_cmd = {
      arguments = "input_text_for_buffer";
      command = "/print \${tg_string_nocolor} prevented";
      conditions = "\${tg_string} =~ ^\\s+/";
      enabled = true;
      hook = "modifier";
      post_action = "none";
      regex = "/.*//";
      return_code = "ok";
    };
  };

  autosort = {
    sorting.replacements = ''[["##", "#"]]'';
    sorting.rules = ''[["core", 0], ["irc", 10], ["*", 1], ["irc.irc_raw", 0], ["irc.server", 1]]'';
  };

  buflist.format = {
    buffer = "\${format_number}\${indent}\${format_nick_prefix}\${color_hotlist}\${name}";
    buffer_current = "\${color:,red}\${format_buffer}";
    hotlist_highlight = "\${color:magenta,black}";
    hotlist_message = "\${color:blue,black}";
    hotlist_private = "\${color:green,black}";
    indent = " ";
  };

  plugins.var.perl = {
    colorize_lines = {
      buffers = "all";
      highlight = true;
      ignore_tags = "irc_ctcp";
      lines = "on";
      own_lines = "on";
      tags = "irc_privmsg";
    };

    notify_send = {
      command = "notify-send $name \"$message\"";
      wait_highlight = 60;
      wait_pm = 180;
    };
  };

  plugins.var.python.go = {
    auto_jump = "off";
    color_name = "black,cyan";
    color_name_highlight = "red,cyan";
    color_name_highlight_selected = "red,brown";
    color_name_selected = "black,brown";
    color_number = "yellow,magenta";
    color_number_selected = "yellow,red";
    message = "Go to: ";
    short_name = "off";
    sort = "number,beginning";
    use_core_instead_weechat = "off";
  };
}