(ns wanijo.attribute.db
  (:require [wanijo.infrastructure.neo4j :as neo4j]))

(neo4j/defquery findy-by-schema
  "MATCH (a:attribute)-->(s:schema)
   WHERE s.uuid = {uuid}
   RETURN a
   ORDER BY a.name")
(defn find-by-schema! [schema-uuid]
  (map :a
       (neo4j/exec-query!
         findy-by-schema
         {:uuid schema-uuid})))

(neo4j/defquery with-name-in-schema
  "MATCH (a:attribute)-[:of]->(s:schema)
   WHERE a.name = {name}
     AND s.uuid = {schema_uuid}
   RETURN a")
(defn with-name-in-schema! [matching-name schema-uuid]
  (-> (neo4j/exec-query! with-name-in-schema
                         {:name matching-name
                          :schema_uuid schema-uuid})
      first
      :a))

(neo4j/defquery create-new
  "MATCH (s:schema {uuid:{schema_uuid}}),
         (u:user {uuid:{user_uuid}})
   CREATE (a:attribute)
   CREATE (a)-[:created_by]->(u)
   CREATE (a)-[:of]->(s)
      SET a.type = {type}
      SET a.name = {name}
      SET a.uuid = {attribute_uuid}
      SET a.required = {required}
      SET a.created_at = {created_at}")
(defn create-new! [attr schema-uuid user-uuid]
  (neo4j/exec-query!
    create-new
    (assoc attr
           :user_uuid user-uuid
           :schema_uuid schema-uuid
           :attribute_uuid (neo4j/uuid)
           :created_at (neo4j/now-str))))

(neo4j/defquery edit
  "MATCH (a:attribute)
   WHERE a.uuid = {uuid}
     SET a.type = {type}
     SET a.name = {name}
     SET a.required = {required}")
(defn edit! [attr]
  (neo4j/exec-query!
    edit
    attr))

(neo4j/defquery delete-by-uuid
  "MATCH (a:attribute)-[c]-()
   WHERE a.uuid = {uuid}
   DELETE c, a")
(defn delete-by-uuid! [uuid]
  (neo4j/exec-query!
    delete-by-uuid
    {:uuid uuid}))

(neo4j/defquery required
  "MATCH (a:attribute)-[:of]->(s:schema {uuid:{schema_uuid}})
   WHERE a.required = 1
   RETURN a
   ORDER BY a.name")
(defn required! [schema-uuid]
  (map :a
       (neo4j/exec-query! required
                          {:schema_uuid schema-uuid})))

(neo4j/defquery schema-of
  "MATCH (a:attribute {uuid:{uuid}})-[:of]->(s:schema)
   RETURN s")
(defn schema-of! [uuid]
  (->> (neo4j/exec-query! schema-of
                          {:uuid uuid})
       (map :s)
       first))

(neo4j/defquery find-by-instance
  "MATCH (i:instance {uuid:{instance_uuid}}),
         (i)-[:of]->(s:schema),
         (a:attribute)-[:of]->(s)
   RETURN a
   ORDER BY a.name")
(defn find-by-instance! [instance-uuid]
  (map :a
       (neo4j/exec-query! find-by-instance
                          {:instance_uuid instance-uuid})))
