(ns bigml-nodered-core.bigml
  (:require clojure.string))

(def bigml (js/require "bigml"))

(defn bigml-error-handler
  ([success error]
   (fn [e i]
     (if (and (nil? e)
              (some? i)
              (.-resource i)
              (.-status i)
              (= (.-code (.-status i)) 5))
       (success i)
       (error (or e (.-status i))))))
  ([cbk]
   (bigml-error-handler #(cbk nil %1) #(cbk %1 nil))))

(defn- wz-wait [handler cbk]
  (fn wait [e i]
    (let [i (or (.-object i) i)
          s (.-status i)]
      (if (and (nil? e)
               (some? s)
               (.-resource i) 
               (not= (.-code s) 5)
               (not= (.-code s) -1))
        (js/setTimeout #(.get handler (.-resource i) wait) 1000)
        ((bigml-error-handler cbk) e i)))))

(defn- bigml-connection [username apikey domain]
  (let [connection (.-BigML bigml)]
    (connection. username apikey (clj->js { :domain domain }))))

(defn- bigml-execution [connection]
  (let [exec (.-Execution bigml)]
    (exec. connection)))

(defn- bigml-script [connection]
  (let [script (.-Script bigml)]
    (script. connection)))

(defn wz-exec-id [script-id inputs cbk opts]
  (let [un (:username opts)
        ak (:apikey opts)
        domain (:domain opts)
        connection (or (:connection opts) (bigml-connection un ak domain))
        exec (bigml-execution connection)
        wait (wz-wait exec cbk)]
    (.create exec script-id (clj->js inputs) wait)))

(defn wz-exec [name whizzml username apikey domain cbk]
  (let [connection (bigml-connection username apikey domain)
        script (bigml-script connection)]
    (.create script whizzml (clj->js { :name name })
             (wz-wait
              script
              (bigml-error-handler 
               #(wz-exec-id (.-resource %1) {} cbk {:connection connection})
               #(cbk %1 nil))))))

(defn upload-source [file username apikey domain opts cbk]
  (let [connection (bigml-connection username apikey domain)
        source (.-Source bigml)
        source (source. connection)]
    (.create source file (wz-wait source cbk))))

