(ns stuff.core
  (:require [clojure.spec.alpha :as s]
            [clojure.spec.gen.alpha :as gen])
  (:gen-class))

(ns-unmap *ns* 'attribute-type)
(ns-unmap *ns* 'validation-type)

(s/def ::string string?)
(s/def ::key ::string)

(defmulti validation-type :type)
(defmethod validation-type "int" [_] ::int-validations)

(s/def ::int-min-validation (s/keys :req-un [::min]))
(s/def ::int-max-validation (s/keys :req-un [::max]))
(s/def ::int-validations (s/or ::int-min-validation ::int-max-validation))

(defmulti attribute-type :type)
(defmethod attribute-type "int" [_] (s/and (s/keys :req-un [::validations]) (s/multi-spec validation-type :type)))

;; (defmethod attribute-type "int" [_] (s/and (s/keys :req-un [::validations]) (s/multi-spec validation-type ::validations)))

(s/def ::attribute (s/and (s/keys :req-un [::label ::key ::type]) (s/multi-spec attribute-type ::type)))

(def int-attr { :key "foo" :label "Foo" :type "int" :validations { :min 0 :max 100 } })
(def string-attr { :key "foo" :label "Foo" :type "string" :validations { :presence true } })

(defn run []
  (s/valid? ::attribute int-attr)
  (s/explain-data ::attribute int-attr))

(run)

;; (s/explain ::validations [ { :min 1 } { :max 3 } ])
;; (gen/generate (spec/gen ::attribute))