             [puppetlabs.puppetdb.utils :as utils]
             [clj-http.client :as client]
             [puppetlabs.puppetdb.config :as conf]
-            [clj-http.util :refer [url-encode]]))
+            [clj-http.util :refer [url-encode]]
+            [clj-http.client :as client]
+            [clojure.string :as str]
+            [fs.core :as fs]))
 
 ;; See utils.clj for more information about base-urls.
 (def ^:dynamic *base-url* nil) ; Will not have a :version.
 
+(defn log-config
+  "Returns a logback.xml string with the specified `log-file` and `log-level`."
+  [log-file log-level]
+  (str "<configuration>
+
+  <appender name=\"FILE\" class=\"ch.qos.logback.core.FileAppender\">
+    <file>" log-file "</file>
+    <append>true</append>
+    <encoder>
+      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level=\"" log-level "\">
+    <appender-ref ref=\"FILE\" />
+  </root>
+</configuration>"))
+
 (defn create-config
   "Creates a default config, populated with a temporary vardir and
-   a fresh hypersql instance"
+  a fresh hypersql instance"
   []
   {:nrepl {}
    :global {:vardir (temp-dir)}

   :web-router-service {:puppetlabs.puppetdb.cli.services/puppetdb-service ""
                        :puppetlabs.puppetdb.metrics/metrics-service "/metrics"}})

(defn current-port
  "Given a trapperkeeper server, return the port of the running jetty instance.
   Note there can be more than one port (i.e. SSL + non-SSL connector). This only
   returns the first one."
  [server]
  (-> @(tka/app-context server)
      (get-in [:WebserverService :jetty9-servers :default :server])


(defn puppetdb-instance
  "Stands up a puppetdb instance with `config`, tears down once `f` returns.
  `services` is a seq of additional services that should be started in addition
  to the core PuppetDB services. Binds *server* and *base-url* to refer to
  the instance."
  ([f] (puppetdb-instance (create-config) f))
  ([config f] (puppetdb-instance config [] f))
  ([config services f]
   (let [[log-file config] (-> config conf/adjust-tk-config assoc-logging-config)
         prefix (get-in config
                        [:web-router-service
                         :puppetlabs.puppetdb.cli.services/puppetdb-service])]
     (try
       (tkbs/with-app-with-config server
         (concat [jetty9-service puppetdb-service message-listener-service command-service webrouting-service metrics-service]
                 services)
         config
         (binding [*server* server
                   *base-url* (merge {:protocol "http"
                                      :host "localhost"
                                      :port (current-port server)}
                                     (when prefix {:prefix prefix}))]
           (f)))
       (finally
         (let [log-contents (slurp log-file)]
           (when-not (str/blank? log-contents)
             (utils/println-err "-------Begin PuppetDB Instance Log--------------------\n"
                                log-contents
                                "\n-------End PuppetDB Instance Log----------------------"))))))))

(defmacro with-puppetdb-instance
  "Convenience macro to launch a puppetdb instance"
