 (ns gclouj.bigquery
   (:require [clojure.walk :as walk])
-  (:import [com.google.gcloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption TableInfo TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode TableInfo$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute LoadJobInfo LoadConfiguration BigQuery$JobOption JobInfo$CreateDisposition JobInfo$WriteDisposition JobStatistics JobStatistics$LoadStatistics JobStatus JobStatus$State FormatOptions]
+  (:import [com.google.gcloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption TableInfo TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode TableInfo$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute LoadJobInfo LoadConfiguration BigQuery$JobOption JobInfo$CreateDisposition JobInfo$WriteDisposition JobStatistics JobStatistics$LoadStatistics JobStatus JobStatus$State FormatOptions QueryJobInfo QueryJobInfo$Priority UserDefinedFunction]
            [com.google.common.hash Hashing]
            [java.util List Collections]))
 

(defn job [service {:keys [project-id job-id] :as job}]
  (to-clojure (.getJob service (JobId/of project-id job-id) (into-array BigQuery$JobOption []))))


(defn load-job [service {:keys [project-id dataset-id table-id] :as table} {:keys [format create-disposition write-disposition]} & uris]
  (let [config-builder (LoadConfiguration/builder (TableId/of project-id dataset-id table-id)
                                                  ({:json (FormatOptions/json)
                                                    :csv  (FormatOptions/csv)} (or format :json)))]
    (.createDisposition config-builder ({:needed JobInfo$CreateDisposition/CREATE_IF_NEEDED
                                         :never JobInfo$CreateDisposition/CREATE_NEVER} (or create-disposition :never)))
    (.writeDisposition config-builder ({:append JobInfo$WriteDisposition/WRITE_APPEND
                                        :empty  JobInfo$WriteDisposition/WRITE_EMPTY
                                        :truncate JobInfo$WriteDisposition/WRITE_TRUNCATE} (or write-disposition :append)))
    (let [configuration (.build config-builder)
          job           (.build (LoadJobInfo/builder configuration ^List uris))]
      (to-clojure (.create service job (into-array BigQuery$JobOption []))))))

    (.defaultDataset builder (DatasetId/of project-id dataset-id))
    (when max-results
      (.maxResults builder max-results))
    (.dryRun builder dry-run?)
    (when max-wait-millis
      (.maxWaitTime builder max-wait-millis))
    (.useQueryCache builder use-cache?)
    (let [q (.build builder)]
      (to-clojure (.query service q)))))

