(local { : Gtk  } (require :lgi))
(local { : view } (require :fennel))
(local lume (require :lume))

(local {: define-command : completion } (require :command))
(local Buffer (require :buffer))

(fn url-escape [s]
  (string.gsub s
               "([^A-Za-z0-9_])"
               #(string.format "%%%02x" (string.byte $1))))

(local searchers
       {:ddg
        {:name "Duck Duck Go"
         :function (fn [term]
                     (.. "https://duckduckgo.com/?q=" (url-escape term)))
         }
        :google
        {:name "Google"
         :function (fn [term]
                     (.. "https://www.google.com/search?q=" (url-escape term)))
         }
        :luai
        {:name "Lua interactive reference manual"
         :function (fn [term]
                     (.. "https://pgl.yoyo.org/luai/i/" (url-escape term)))
         }
        })


(fn match-engines [term]
  (icollect [keyword {: name  : function} (pairs searchers)]
    (if (string.match keyword term)
        (completion {
                     :text keyword
                     :value keyword
                     :widget (Gtk.Label { :label name })
                     }))))


(define-command
 "search"
 [[:term
   #[(completion {:text $1})]
   #""]
  [:buffer
   #(lume.map (Buffer.match $1) #(completion { :text $1.name :value $1 }))
   #$1.buffer.name]
  [:engine match-engines  #:ddg]]
 (fn [{: term : engine : buffer}]
   (buffer:visit ((. (. searchers engine) :function) term))))