<commit_before>(ns cmr.system-int-test.utils.tag-util
  "This contains utilities for testing tagging"
  (:require [cmr.transmit.tag :as tt]
            [clojure.test :refer [is]]
            [cmr.system-int-test.system :as s]
            [cmr.system-int-test.utils.metadata-db-util :as mdb]
            [cmr.transmit.echo.tokens :as tokens]
            [cmr.common.mime-types :as mt]))

(defn make-tag
  "Makes a valid tag"
  ([]
   (make-tag nil))
  ([attributes]
   (merge {:namespace "org.nasa.something"
           :category "QA"
           :value "value"
           :description "A very good tag"}
          attributes)))

(defn- process-response
  [{:keys [status body]}]
  (if (map? body)
    (assoc body :status status)
    {:status status
     :body body}))

(defn create-tag
  "Creates a tag."
  ([token tag]
   (create-tag token tag nil))
  ([token tag options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/create-tag (s/context) tag options)))))

(defn get-tag
  "Retrieves a tag by concept id"
  [concept-id]
  (process-response (tt/get-tag (s/context) concept-id {:is-raw? true})))

(defn update-tag
  "Updates a tag."
  ([token concept-id tag]
   (update-tag token concept-id tag nil))
  ([token concept-id tag options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/update-tag (s/context) concept-id tag options)))))


(defn delete-tag
  "Deletes a tag"
  ([token concept-id]
   (delete-tag token concept-id nil))
  ([token concept-id options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/delete-tag (s/context) concept-id options)))))

(defn associate-by-query
  "Associates a tag with collections found with a JSON query"
  ([token concept-id condition]
   (associate-by-query token concept-id condition nil))
  ([token concept-id condition options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/associate-tag-by-query (s/context) concept-id {:condition condition} options)))))

(defn disassociate-by-query
  "Disassociates a tag with collections found with a JSON query"
  ([token concept-id condition]
   (disassociate-by-query token concept-id condition nil))
  ([token concept-id condition options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/disassociate-tag-by-query (s/context) concept-id {:condition condition} options)))))

(defn save-tag
  "A helper function for creating or updating tags for search tests. If the tag does not have a
  :concept-id it saves it. If the tag has a :concept-id it updates the tag. Returns the saved tag
  along with :concept-id, :revision-id, :errors, and :status"
  ([token tag]
   (let [tag-to-save (select-keys tag [:namespace :category :value :description])
         response (if-let [concept-id (:concept-id tag)]
                    (update-tag token concept-id tag-to-save)
                    (create-tag token tag-to-save))
         tag (into tag (select-keys response [:status :errors :concept-id :revision-id]))]

     (if (= (:revision-id tag) 1)
       ;; Get the originator id for the tag
       (assoc tag :originator-id (tokens/get-user-id (s/context) token))
       tag)))
  ([token tag associated-collections]
   (let [saved-tag (save-tag token tag)
         ;; Associate the tag with the collections using a query by concept id
         condition {:or (map #(hash-map :concept_id (:concept-id %)) associated-collections)}
         ;; TODO change this to use the POST /associations endpoint
         response (associate-by-query token (:concept-id saved-tag) condition)]
     (assert (= 200 (:status response)) (pr-str condition))
     (assoc saved-tag :revision-id (:revision-id response)))))

(defn search
  "Searches for tags using the given parameters"
  [params]
  (process-response (tt/search-for-tags (s/context) params {:is-raw? true})))

(defn assert-tag-saved<commit_msg>Removing TODO we don't need to do now.<commit_after>(ns cmr.system-int-test.utils.tag-util
  "This contains utilities for testing tagging"
  (:require [cmr.transmit.tag :as tt]
            [clojure.test :refer [is]]
            [cmr.system-int-test.system :as s]
            [cmr.system-int-test.utils.metadata-db-util :as mdb]
            [cmr.transmit.echo.tokens :as tokens]
            [cmr.common.mime-types :as mt]))

(defn make-tag
  "Makes a valid tag"
  ([]
   (make-tag nil))
  ([attributes]
   (merge {:namespace "org.nasa.something"
           :category "QA"
           :value "value"
           :description "A very good tag"}
          attributes)))

(defn- process-response
  [{:keys [status body]}]
  (if (map? body)
    (assoc body :status status)
    {:status status
     :body body}))

(defn create-tag
  "Creates a tag."
  ([token tag]
   (create-tag token tag nil))
  ([token tag options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/create-tag (s/context) tag options)))))

(defn get-tag
  "Retrieves a tag by concept id"
  [concept-id]
  (process-response (tt/get-tag (s/context) concept-id {:is-raw? true})))

(defn update-tag
  "Updates a tag."
  ([token concept-id tag]
   (update-tag token concept-id tag nil))
  ([token concept-id tag options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/update-tag (s/context) concept-id tag options)))))


(defn delete-tag
  "Deletes a tag"
  ([token concept-id]
   (delete-tag token concept-id nil))
  ([token concept-id options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/delete-tag (s/context) concept-id options)))))

(defn associate-by-query
  "Associates a tag with collections found with a JSON query"
  ([token concept-id condition]
   (associate-by-query token concept-id condition nil))
  ([token concept-id condition options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/associate-tag-by-query (s/context) concept-id {:condition condition} options)))))

(defn disassociate-by-query
  "Disassociates a tag with collections found with a JSON query"
  ([token concept-id condition]
   (disassociate-by-query token concept-id condition nil))
  ([token concept-id condition options]
   (let [options (merge {:is-raw? true :token token} options)]
     (process-response (tt/disassociate-tag-by-query (s/context) concept-id {:condition condition} options)))))

(defn save-tag
  "A helper function for creating or updating tags for search tests. If the tag does not have a
  :concept-id it saves it. If the tag has a :concept-id it updates the tag. Returns the saved tag
  along with :concept-id, :revision-id, :errors, and :status"
  ([token tag]
   (let [tag-to-save (select-keys tag [:namespace :category :value :description])
         response (if-let [concept-id (:concept-id tag)]
                    (update-tag token concept-id tag-to-save)
                    (create-tag token tag-to-save))
         tag (into tag (select-keys response [:status :errors :concept-id :revision-id]))]

     (if (= (:revision-id tag) 1)
       ;; Get the originator id for the tag
       (assoc tag :originator-id (tokens/get-user-id (s/context) token))
       tag)))
  ([token tag associated-collections]
   (let [saved-tag (save-tag token tag)
         ;; Associate the tag with the collections using a query by concept id
         condition {:or (map #(hash-map :concept_id (:concept-id %)) associated-collections)}
         response (associate-by-query token (:concept-id saved-tag) condition)]
     (assert (= 200 (:status response)) (pr-str condition))
     (assoc saved-tag :revision-id (:revision-id response)))))

(defn search
  "Searches for tags using the given parameters"
  [params]
  (process-response (tt/search-for-tags (s/context) params {:is-raw? true})))

(defn assert-tag-saved
{'fraction_non_alphanumeric': 0.13733417561591915, 'fraction_numerical': 0.0010107391029690461, 'mean_word_length': 3.1466736511262443, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5009736', 'n_tokens_mistral': 2605, 'n_tokens_neox': 2481, 'n_words': 813}