   (:import [java.util.concurrent Executors]))
 
 (defn valid-name?
-  "check if s is a valid-name"
+  "check if s is a valid-name, i.e. a non-empty sequence of the
+  characters a-zA-Z0-9 - and _"
   [s]
   (boolean (re-matches #"^[-a-zA-Z0-9_]+$" s)))
 

  current-system nil)

(defn run-system
  [{:keys [iniconfig command-sections] :as system}]
  (alter-var-root #'current-system (constantly system))
  (worker/start (meta-runner/make-meta-runner system command-sections)))

(defn get-filesystems-for-section
  [system section-name]
  (or (misc/trimmed-lines-from-string (get-in system [:iniconfig section-name "filesystems"]))
      (get-in system [:config :filesystems])
      (misc/die (str "no filesystems defined in section " section-name))))

   :filesystems (misc/trimmed-lines-from-string
                 (get-in iniconfig [inihelper/main-section-name "filesystems"]))
   :rmq-prefix (get-in iniconfig [inihelper/main-section-name "rmq-prefix"] inihelper/main-section-name)
   :es-url (or (get-in iniconfig [inihelper/main-section-name "es-url"])
               "http://localhost:9200")})

(defn- inidie
  "call misc/die, put the section name and iniconfig source in front
  of the error message"
  [iniconfig section msg]
  (misc/die (format "while parsing section %s in %s: %s"
                    section
                    (-> iniconfig meta :source)
                    msg)))

(defn- make-die-fn
  "return fn wrapping misc/die, put the section name and iniconfig
  source in front of the error message"
  [iniconfig section]
  (partial inidie iniconfig section))

(defn- validate-filesystems
  "validate filesystem names. call die with an error message, if validation fails"
  [filesystems die]
  (doseq [fs filesystems]
    (when-not (valid-name? fs)
      (die (format "the filesystem name %s is not valid" (pr-str fs))))))

(defn- validate-main-section
  "validate main section"
  [{:keys [rmq-prefix filesystems]} die]
  (when-not (valid-name? rmq-prefix)
    (die (format "rmq-prefix value %s is not valid" (pr-str rmq-prefix))))
  (validate-filesystems filesystems die))


(defn- parse-main-section
  "parse nozzle's main section. the result will be stored as :config inside the system map"
  [iniconfig]
  (let [res (parse-main-section* iniconfig)
        die (make-die-fn iniconfig inihelper/main-section-name)]
    (validate-main-section res die)
    res))

(defn make-system [iniconfig command-sections]
  "create a system map. the system map is where we store our
  configuration data and some state. the system map contains the followings keys:

  :iniconfig the ini configuration
  :command-sections command sections as passed on the command line
  :config parsed values from the main section
  :thread-pool the thread pool which should be used by workers
  :name->obj an atom, mapping section names as specified in the ini
             config to the objects which we created."
  {:iniconfig iniconfig
   :command-sections command-sections
   :config (parse-main-section iniconfig)
