(in-package :panettone.util)

(defun integer-env (var &key default)
  (or
   (when-let ((str (uiop:getenvp var)))
     (try-parse-integer str))
   default))

(defun add-missing-base64-padding (s)
  "Add any missing padding characters to the (un-padded) base64 string `S', such
that it can be successfully decoded by the `BASE64' package"
  ;; I apologize
  (let* ((needed-padding (mod (length s) 4))
         (pad-chars (if (zerop needed-padding) 0 (- 4 needed-padding))))
    (format nil "~A~v@{~A~:*~}" s pad-chars "=")))

(defun and-where (clauses)
  "Combine all non-nil clauses in CLAUSES into a single S-SQL WHERE form"
  (let ((clauses (remove nil clauses)))
    (if (null clauses) t
        (reduce (lambda (x y) `(:and ,x ,y)) clauses))))

(defun and-where* (&rest clauses)
  "Combine all non-nil clauses in CLAUSES into a single S-SQL WHERE form"
  (and-where clauses))

(defmacro define-build-time-var
    (name value-if-not-in-build &optional (doc nil))
  `(defvar ,name
     (or (when-let ((package (find-package :build)))
           (let ((sym (find-symbol ,(symbol-name name) package)))
             (when (boundp sym) (symbol-value sym))))
         ,value-if-not-in-build)
     ,doc))

(defun ->dir (dir)
  (if (char-equal (uiop:last-char dir) #\/)
      dir
      (concatenate 'string dir "/")))