 (ns taoensso.faraday.tests.main
-  (:require [expectations           :as test :refer :all]
-            [taoensso.encore        :as encore]
-            [taoensso.faraday       :as far]
-            [taoensso.nippy         :as nippy])
-  (:import [com.amazonaws.auth BasicAWSCredentials]
-           [com.amazonaws.internal StaticCredentialsProvider]))
+  (:require [expectations     :as test :refer :all]
+            [taoensso.encore  :as encore]
+            [taoensso.faraday :as far]
+            [taoensso.nippy   :as nippy])
+  (:import  [com.amazonaws.auth BasicAWSCredentials]
+            [com.amazonaws.internal StaticCredentialsProvider]))
 
 ;; TODO LOTS of tests still outstanding, PRs very, very welcome!!
 

;;;; Config & setup

(def ^:dynamic *client-opts*
  (merge {:access-key (get (System/getenv) "AWS_DYNAMODB_ACCESS_KEY")
          :secret-key (get (System/getenv) "AWS_DYNAMODB_SECRET_KEY")}
         (when-let [endpoint (get (System/getenv) "AWS_DYNAMODB_ENDPOINT")] {:endpoint endpoint})))

(def ttable :faraday.tests.main)

(defn- before-run {:expectations-options :before-run} []
  (println "Setting up testing environment...")
  (far/ensure-table *client-opts* ttable [:id :n]
    {:throughput  {:read 1 :write 1}

;; (expect (interaction (println anything&)) (println 5))
;; (expect (interaction (println Long))      (println 5))

;;; Test AWSCredentialProvider
(let [i0 {:id 0 :name "foo"}
      i1 {:id 1 :name "bar"}
      i2 {:id 2 :name "baz"}
      creds    (BasicAWSCredentials. (:access-key *client-opts*)
                                     (:secret-key *client-opts*))
      provider (StaticCredentialsProvider. creds)
      endpoint (:endpoint *client-opts*)]

  (binding [*client-opts* {:provider provider
                           :endpoint endpoint}]

    (expect ; Batch put
      [i0 i1 nil]
      (do
        (far/batch-write-item *client-opts*
          {ttable {:delete [{:id 0} {:id 1} {:id 2}]}})
        ;;
        (far/batch-write-item *client-opts* {ttable {:put [i0 i1]}})
        [(far/get-item *client-opts* ttable {:id  0})
         (far/get-item *client-opts* ttable {:id  1})
         (far/get-item *client-opts* ttable {:id -1})]))))

;;; Test `list-tables` lazy sequence
;; Creates a _large_ number of tables so only run locally
(let [endpoint (:endpoint *client-opts*)]
  (when (and endpoint (.contains ^String endpoint "localhost"))
    (expect
      (let [;; Generate > 100 tables to exceed the batch size limit:
            tables (map #(keyword (str "test_" %)) (range 102))]
        (doseq [table tables]
          (far/ensure-table *client-opts* table [:id :n]
            {:throughput  {:read 1 :write 1}
             :block?      true}))
        (let [table-count (count (far/list-tables *client-opts*))]
          (doseq [table tables]
            (far/delete-table *client-opts* table))
          (> table-count 100))))))
