(in-package #:lispsearch)

;;;; Catalog ingestion. The authoritative system list is a plain newline-
;;;; delimited file (see M0 spike, lispsearch-plan.md §2). No GitHub API, no auth.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require :sb-md5))

(defun fetch-catalog (&key (url *catalog-url*))
  "GET the catalog file and return its body as a string."
  (dex:get url :connect-timeout *http-timeout* :read-timeout *http-timeout*))

(defun parse-catalog (text)
  "Parse catalog TEXT into a deduped list of (registry-name . system-name),
in first-seen order. registry-name is the raw OCI repo key (the line as-is);
system-name is the decoded ASDF/install name."
  (let ((seen (make-hash-table :test 'equal))
        (out '()))
    (dolist (line (split-lines text) (nreverse out))
      (unless (gethash line seen)
        (setf (gethash line seen) t)
        (push (cons line (decode-name line)) out)))))

(defun catalog-sha (text)
  "Stable lowercase hex MD5 of catalog TEXT, stored in meta to detect changes."
  (string-downcase
   (with-output-to-string (s)
     (loop for byte across (sb-md5:md5sum-string text)
           do (format s "~2,'0X" byte)))))
