  (ns auto-ap.db.utils
  (:require [clojure.string :as str]
            [clojure.edn :as edn]
            [clojure.java.jdbc :as j]
            [config.core :refer [env]]
            [honeysql.core :as sql]))

(defn snake->kebab [s]
  (str/replace s #"_" "-"))

(defn kebab->snake [s]
  (str/replace s #"-" "_"))

(defn db->clj
  ([x]
   (let [kebabed (into {}
                       (map
                        (fn [[k v]]
                          [(keyword (snake->kebab (name k))) v])
                        x))
         merged (if (:data kebabed)
                  (update kebabed :data edn/read-string)
                  kebabed)]
     merged)))

(defn snake [x]
  (into {}
        (map
         (fn [[k v]]
           [(keyword (kebab->snake (name k))) v])
         x)))

(defn clj->db [x]
  (let [snaked (snake x) 
        unmerged (if (:data snaked)
                   (update snaked :data pr-str)
                   snaked)]
    unmerged))



(defn merge-data [{:keys [data] :as x}]
  (merge x (edn/read-string data)))

(def ^{:dynamic true} current-conn nil)

(defn get-conn []
  (if current-conn
    current-conn
    (let [db-host (:server (:db env))
          db-port 5432
          db-name "autoap"]
      {:classname "org.postgresql.Driver" ; must be in classpath
       #_#_:ssl true
       #_#_:sslfactory "org.postgresql.ssl.NonValidatingFactory"
       :subprotocol "postgresql"
       :subname (str "//" db-host ":" db-port "/" db-name)
       :user "ap"
       :password "fifteen-invoices-imported!"})))

(defn query [q]
  (let [formatted (sql/format q)]
    (println "Executing query " q " SQL: " formatted)

    (map db->clj (j/query (get-conn) formatted))))

(defn execute! [q]
  (let [formatted (sql/format q)]
    (println "Executing query " q " SQL: " formatted)
    (j/execute! (get-conn) formatted)))
