(ns spec-tools.form
  (:require [clojure.spec.alpha :as s]))

(defmulti resolve-form
  (fn [x] (cond
            (or (qualified-keyword? x) (seq? x)) ::identity
            (or (s/spec? x) (s/regex? x)) ::spec
            :else x))
  :default ::default)

(defmethod resolve-form ::spec [x] (s/form x))
(defmethod resolve-form ::identity [x] x)
(defmethod resolve-form ::default [_] ::s/unknown)

(defmethod resolve-form any? [_] `any?)
(defmethod resolve-form some? [_] `some?)
(defmethod resolve-form number? [_] `number?)
(defmethod resolve-form integer? [_] `integer?)
(defmethod resolve-form int? [_] `int?)
(defmethod resolve-form pos-int? [_] `pos-int?)
(defmethod resolve-form neg-int? [_] `neg-int?)
(defmethod resolve-form nat-int? [_] `nat-int?)
(defmethod resolve-form float? [_] `float?)
(defmethod resolve-form double? [_] `double?)
(defmethod resolve-form boolean? [_] `boolean?)
(defmethod resolve-form string? [_] `string?)
(defmethod resolve-form ident? [_] `ident?)
(defmethod resolve-form simple-ident? [_] `simple-ident?)
(defmethod resolve-form qualified-ident? [_] `qualified-ident?)
(defmethod resolve-form keyword? [_] `keyword?)
(defmethod resolve-form simple-keyword? [_] `simple-keyword?)
(defmethod resolve-form qualified-keyword? [_] `qualified-keyword?)
(defmethod resolve-form symbol? [_] `symbol?)
(defmethod resolve-form simple-symbol? [_] `simple-symbol?)
(defmethod resolve-form qualified-symbol? [_] `qualified-symbol?)
(defmethod resolve-form uuid? [_] `uuid?)
#?(:clj (defmethod resolve-form uri? [_] `uri?))
#?(:clj (defmethod resolve-form decimal? [_] `decimal?))
(defmethod resolve-form inst? [_] `inst?)
(defmethod resolve-form seqable? [_] `seqable?)
(defmethod resolve-form indexed? [_] `indexed?)
(defmethod resolve-form map? [_] `map?)
(defmethod resolve-form vector? [_] `vector?)
(defmethod resolve-form list? [_] `list?)
(defmethod resolve-form seq? [_] `seq?)
(defmethod resolve-form char? [_] `char?)
(defmethod resolve-form set? [_] `set?)
(defmethod resolve-form nil? [_] `nil?)
(defmethod resolve-form false? [_] `false?)
(defmethod resolve-form true? [_] `true?)
(defmethod resolve-form zero? [_] `zero?)
#?(:clj (defmethod resolve-form rational? [_] `rational?))
(defmethod resolve-form coll? [_] `coll?)
(defmethod resolve-form empty? [_] `empty?)
(defmethod resolve-form associative? [_] `associative?)
(defmethod resolve-form sequential? [_] `sequential?)
#?(:clj (defmethod resolve-form ratio? [_] `ratio?))
#?(:clj (defmethod resolve-form bytes? [_] `bytes?))
