 (ns graphql-clj.spec
-  (:require [clojure.spec :as s]
+  (:require [clojure.spec]
             [clojure.string :as str]
             [graphql-clj.visitor :as v]
             [clojure.walk :as walk]))

  ([path] (when (> (count path) 0) (str/join delimiter path))) ;; Empty path vector = empty string = malformed keyword
  ([node-type path] (path->name (cons node-type path))))

(defn- field->spec [schema-hash {:keys [v/path]}] ;; TODO ignores required, rethink approach and notation for required fields
  (named-spec schema-hash path))

(defn- to-keys [schema-hash fields]
  (list 'clojure.spec/keys
        :opt-un (map (partial field->spec schema-hash) (remove :required fields))
        :req-un (map (partial field->spec schema-hash) (filter :required fields))))

(defmulti spec-for
  (fn [_ {:keys [node-type type-name]}]

      (extension-type schema-hash type-def)
      (base-type schema-hash type-def))))

(defmethod spec-for :variable-definition [schema-hash {:keys [v/path type-name]}]
  (register-idempotent schema-hash (into ["var"] path) (named-spec schema-hash [type-name])))

(defmethod spec-for :input-definition [schema-hash {:keys [type-name fields]}]
  (register-idempotent schema-hash [type-name] (to-keys schema-hash fields)))
