 (ns me.shenfeng.http.client
+  (:refer-clojure :exclude [get])
   (:require [clojure.string :as str])
   (:import [me.shenfeng.http.client HttpClientConfig HttpClient
             IResponseHandler RespListener RespListener$IFilter]
+           javax.xml.bind.DatatypeConverter
            (java.net URI URLEncoder)
            me.shenfeng.http.HttpMethod))
 

  [options resp & handler]
  `(request* ~options (fn [~resp] ~@handler)))

(comment
  @(request {:url "http://www.cnn.com/"}
            {:keys [status body headers] :as resp}
            (if status ; nil on exceptions
              (do (println "Body: " body) body)
              (do (println "Exceptiond: " resp) resp))))

(comment ; TODO

  (defn- url-encode
    "Returns an UTF-8 URL encoded version of the given string."
    [unencoded]
    (URLEncoder/encode unencoded "UTF-8"))

  (defn- generate-query-string
    "Params: {:param1 \"value1\" :params2 \"value2\" :param3 [\"value3\" \"value4\"}

    Return Http Form encoded bytes array. used as HTTP body. Need to set

    Content-Type: application/x-www-form-urlencoded

    in the Request's Headers for server to properly understand it"
    [params]
    (.getBytes (str/join "&"
                         (mapcat (fn [[k v]]
                                   (if (sequential? v)
                                     (map #(str (url-encode (name %1))
                                                "="
                                                (url-encode (str %2)))
                                          (repeat k) v)
                                     [(str (url-encode (name k))
                                           "="
                                           (url-encode (str v)))]))
                                 params))
               "UTF-8")))
            (assoc m (if keywordize-headers? (keyword (str/lower-case k))
                         (str/lower-case k)) v))
          {} headers))

(defn- url-encode [unencoded] (URLEncoder/encode unencoded "UTF-8"))
(defn- utf8-bytes [#^String s] (.getBytes s "UTF-8"))
(defn- base64-encode [bytes]
  (DatatypeConverter/printBase64Binary bytes))
(defn- basic-auth-value [basic-auth]
  (let [basic-auth (if (string? basic-auth)
                     basic-auth
                     (str (first basic-auth) ":" (second basic-auth)))]
    (str "Basic " (base64-encode (utf8-bytes basic-auth)))))

(defn- form-body [params]
  (.getBytes (str/join "&"
                       (mapcat (fn [[k v]]
                                 (if (sequential? v)
                                   (map #(str (url-encode (name %1))
                                              "="
                                              (url-encode (str %2)))
                                        (repeat k) v)
                                   [(str (url-encode (name k))
                                         "="
                                         (url-encode (str v)))]))
                               params))
             "UTF-8"))

(defonce default-client (atom nil))

