;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC

(ns frontend-tests.plugins.text-test
  (:require
   [app.main.data.workspace.texts :as dwt]
   [app.main.store :as st]
   [app.plugins.fonts :as fonts]
   [app.plugins.format :as format]
   [app.plugins.register :as r]
   [app.plugins.shape :as shape]
   [app.plugins.text :as plugins.text]
   [app.plugins.utils :as u]
   [cljs.test :as t :include-macros true]
   [frontend-tests.helpers.mock :as mock]))

(def ^:private plugin-id "00000000-0000-0000-0000-000000000000")

;; Regression coverage for issue #9780.
;;
;; `letterSpacing` accepts negative tracking in the product UI (-200..200,
;; see typography.cljs), but the plugin validator regex rejected any leading
;; minus, so negative values were refused. `letter-spacing-re` is the shared
;; predicate behind both the shape- and range-level setters; pin its
;; accept/reject contract here.

(def ^:private letter-spacing-re @#'plugins.text/letter-spacing-re)

(defn- valid? [s] (boolean (re-matches letter-spacing-re s)))

(t/deftest letter-spacing-re-accepts-negative-values
  (t/is (valid? "-0.56"))
  (t/is (valid? "-12"))
  (t/is (valid? "-200")))

(t/deftest letter-spacing-re-accepts-non-negative-values
  (t/is (valid? "0"))
  (t/is (valid? "12"))
  (t/is (valid? "1.5")))

(t/deftest letter-spacing-re-rejects-non-numeric
  (t/is (not (valid? "abc")))
  (t/is (not (valid? "1-2")))
  (t/is (not (valid? "--1"))))


(t/deftest font-apply-to-text-uses-font-id-not-shape-id
  (let [file-id  (random-uuid)
        page-id  (random-uuid)
        shape-id (random-uuid)
        font     (fonts/font-proxy
                  plugin-id
                  {:id "font-id"
                   :family "Inter"
                   :name "Inter"
                   :variants [{:id "regular"
                               :name "Regular"
                               :weight "400"
                               :style "normal"}]})
        text     (shape/shape-proxy plugin-id file-id page-id shape-id)
        captured (atom nil)]
    (with-redefs [r/check-permission (constantly true)
                  u/page-active? (constantly true)
                  dwt/update-attrs
                  (fn [id attrs]
                    (reset! captured {:id id :attrs attrs})
                    :update-attrs)
                  st/emit! mock/noop]
      (.applyToText font text nil)
      (t/is (= shape-id (:id @captured)))
      (t/is (= "font-id" (get-in @captured [:attrs :font-id]))))))

(t/deftest font-apply-to-range-uses-hidden-range-bounds
  (let [file-id  (random-uuid)
        page-id  (random-uuid)
        shape-id (random-uuid)
        font     (fonts/font-proxy
                  plugin-id
                  {:id "font-id"
                   :family "Inter"
                   :name "Inter"
                   :variants [{:id "regular"
                               :name "Regular"
                               :weight "400"
                               :style "normal"}]})
        range    (plugins.text/text-range-proxy plugin-id file-id page-id shape-id 1 4)
        captured (atom nil)]
    (with-redefs [r/check-permission (constantly true)
                  u/page-active? (constantly true)
                  dwt/update-text-range
                  (fn [id start end attrs]
                    (reset! captured {:id id
                                      :start start
                                      :end end
                                      :attrs attrs})
                    :update-text-range)
                  st/emit! mock/noop]
      (.applyToRange font range nil)
      (t/is (= shape-id (:id @captured)))
      (t/is (= 1 (:start @captured)))
      (t/is (= 4 (:end @captured)))
      (t/is (= "font-id" (get-in @captured [:attrs :font-id]))))))

(t/deftest text-range-shape-returns-a-shape-proxy
  (let [file-id  (random-uuid)
        page-id  (random-uuid)
        shape-id (random-uuid)
        range    (plugins.text/text-range-proxy plugin-id file-id page-id shape-id 0 3)]
    (with-redefs [format/shape-proxy shape/shape-proxy]
      (let [text-shape (.-shape range)]
        (t/is (shape/shape-proxy? text-shape))
        (t/is (= shape-id (aget text-shape "$id")))))))
