let Lib = ./dhall/lib.dhall

let List/map = Lib.List/map

let Ini = ./ini/ini.dhall

in  λ ( imports
      : { -- Take an aerc filter from the aerc distribution /share directory
          aercFilter : Text → Text
        , Ini/externs : Ini.Externs
        }
      ) →
      { accounts =
          imports.Ini/externs.renderIni
            { globalSection = [] : Ini.Section
            , sections =
              [ { name = "mail"
                , value =
                  [ { name = "archive", value = "Archive" }
                  , { name = "copy-to", value = "Sent" }
                  , { name = "default", value = "INBOX" }
                  , { name = "from", value = "Profpatsch <mail@profpatsch.de>" }
                  , { name = "source", value = "maildir://~/.Mail/mail" }
                  , { name = "postpone", value = "Drafts" }
                  ]
                }
              ]
            }
      , aerc =
          imports.Ini/externs.renderIni
            { globalSection = [] : Ini.Section
            , sections =
              [ { name = "filters"
                , value =
                  [ { name = "text/html", value = imports.aercFilter "html" }
                  , let _ = "-- TODO: this awk should be taken from nix!"

                    in  { name = "text/*"
                        , value = "awk -f ${imports.aercFilter "plaintext"}"
                        }
                  ]
                }
              ]
            }
      , binds =
          let
              -- keybinding and command to run
              Key =
                { ctrl : Bool, key : Text, cmd : Text }

          in  let
                  -- render a key to config format
                  renderKey =
                    λ(k : Key) →
                      if    k.ctrl
                      then  { name = "<C-${k.key}>", value = k.cmd }
                      else  { name = k.key, value = k.cmd }

              let

                  -- render a list of keys to config format
                  renderKeys =
                    λ(keys : List Key) →
                      List/map Key (Ini.NameVal Text) renderKey keys

              let
                  -- create a section whith a name and a list of keys
                  sect =
                    λ(section : Text) →
                    λ(keys : List Key) →
                      { name = section, value = renderKeys keys }

              let

                  -- set key without modifiers
                  key =
                    λ(key : Text) → { key }

              let
                  -- set special key without modifiers
                  special =
                    λ(key : Text) → { key = "<${key}>" }

              let
                  -- no modifier
                  none =
                    { ctrl = False }

              let
                  -- set control key
                  ctrl =
                    { ctrl = True }

              let
                  -- set a command to execute
                  cmd =
                    λ(cmd : Text) → { cmd = ":${cmd}<Enter>" }

              let
                  -- set a command, but stay on the prompt
                  prompt =
                    λ(cmd : Text) → { cmd = ":${cmd}<Space>" }

              let config =
                    { globalSection =
                        renderKeys
                          [ ctrl ∧ key "p" ∧ cmd "prev-tab"
                          , ctrl ∧ key "n" ∧ cmd "next-tab"
                          , ctrl ∧ key "t" ∧ cmd "term"
                          ]
                    , sections =
                      [ sect
                          "messages"
                          [ ctrl ∧ key "q" ∧ cmd "quit"
                          , none ∧ special "Up" ∧ cmd "prev"
                          , none ∧ special "Down" ∧ cmd "next"
                          , none ∧ special "PgUp" ∧ cmd "prev 100%"
                          , none ∧ special "PgDn" ∧ cmd "next 100%"
                          , none ∧ key "g" ∧ cmd "select 0"
                          , none ∧ key "G" ∧ cmd "select -1"
                          , ctrl ∧ key "Up" ∧ cmd "prev-folder"
                          , ctrl ∧ key "Down" ∧ cmd "next-folder"
                          , none ∧ key "v" ∧ cmd "mark -t"
                          , none ∧ key "V" ∧ cmd "mark -v"
                          , none ∧ special "Enter" ∧ cmd "view"
                          , none ∧ key "c" ∧ cmd "compose"
                          , none ∧ key "|" ∧ prompt "pipe"
                          , none ∧ key "t" ∧ prompt "term"
                          , none ∧ key "/" ∧ prompt "search"
                          , none ∧ key "n" ∧ cmd "next-result"
                          , none ∧ key "N" ∧ cmd "prev-result"
                          , none ∧ special "Esc" ∧ cmd "clear"
                          ]
                      , sect "view" [ none ∧ key "q" ∧ cmd "close" ]
                      ]
                    }

              in  imports.Ini/externs.renderIni config
      }
