(ns wanijo.instance.domain
  (:require [wanijo.specs :as specs]
            [wanijo.attribute.domain :as domain-attr]
            [wanijo.schema.db :as db-schema]
            [wanijo.tag.db :as db-tag]
            [wanijo.link.db :as db-link]
            [clojure.spec.alpha :as spec]))

(spec/def ::instance
  (spec/keys :req-un [::specs/uuid
                      ::specs/created_at
                      ::specs/updated_at
                      ::specs/name]))
(spec/def ::properties
  (spec/coll-of
    (spec/keys :req-un [::specs/uuid
                        ::specs/created_at
                        ::specs/updated_at
                        ::domain-attr/attribute])))
(spec/def ::target ::instance)
(spec/def ::source ::instance)
(spec/def ::tags
  (spec/coll-of ::db-tag/tag))
(spec/def ::contains-schema
  (spec/keys :req-un [::db-schema/schema]))

(spec/def ::instance-with-tags-and-props
  (spec/merge ::instance
              (spec/keys :req-un [::tags
                                  ::properties])))
(spec/def ::instances-with-tags-and-props
  (spec/coll-of ::instance-with-tags-and-props))

(spec/def ::instance-with-schema
  (spec/merge ::instance ::contains-schema))

(spec/def ::prop-tuple-values
  (spec/keys :req-un [::specs/uuid
                      ::specs/now
                      ::value
                      ::specs/instance_uuid
                      ::specs/attribute_uuid]))
(spec/def ::prop-tuple
  (spec/coll-of
    (spec/tuple fn? ::prop-tuple-values)))

(spec/def ::links-out
  (spec/coll-of
    (spec/keys :req-un [::db-link/link
                        ::target
                        ::db-schema/schema
                        ::tags])))

(spec/def ::links-in
  (spec/coll-of
    (spec/keys :req-un [::db-link/link
                        ::source
                        ::db-schema/schema
                        ::tags])))

(spec/def ::contains-full-information
  (spec/keys :req-un [::properties
                      ::links-out
                      ::links-in
                      ::tags]))
(spec/def ::full-instance
  (spec/merge ::instance-with-schema
              ::contains-full-information))
