(ns dda.build.gopass
  (:require [orchestra.core :refer [defn-spec]]
            [clojure.spec.test.alpha :as st]
            [cheshire.core :refer [parse-string generate-string]]
            [dda.build.devops :as d]
            [dda.build.gopass.domain :as domain]
            [dda.build.c4k.domain :as c4k-d]
            [dda.build.infrastructure :as i]))

(def default
  (merge d/default {:c4k-auth-filename "c4k-auth.yaml"}))

(defn-spec run-gopass-command! string?
  [devops ::d/devops
   entry ::domain/gopass-entry]
  (let [config (merge default devops)
        c (domain/gopass-show-command entry)]
    (i/execute-output! c config)))

(defn-spec resolve-gopass! ::resolved-config
  "Resolves gopass values inside a map of key names and entries
   
   entries may either contain only a path 
     {:path \"test/path\"} 
   or a path and a field
     {:path \"test/path\" :field \"field\"}
   "
  [devops ::d/devops
   config ::domain/config]
  (update-vals config #(run-gopass-command! devops %)))

(defn-spec insert-gopass! nil?
  "Inserts values from the resolved auth config into the c4k auth
   
   Default: c4k-auth.yaml
   can be changed by adding another value for ':c4k-auth-filename'
   "
  [devops ::d/devops
   resolved-config ::resolved-config]
  (let [config (merge default devops)
        default-c4k-auth (parse-string (slurp (c4k-d/auth-path config))
                                       (fn [k] (keyword (.toLowerCase k))))]
    (->> default-c4k-auth
         (merge resolved-config)
         (generate-string)
         (spit (domain/config-path config)))))


(st/instrument `run-gopass-command!)
(st/instrument `resolve-gopass!)
(st/instrument `insert-gopass!)