(ns sydnix-cli.commands.rebuild
  (:require [babashka.process :as p]))

(defn- parse-target [target]
  (when-some [[_ _ user host] (re-matches #"(([-a-zA-Z0-9_]+)@)?(.+)"
                                          target)]
    {:user user :host host}))

(defn- str-target [{:keys [user host]}]
  (str (when user
         (str user "@"))
       host))

(def command-options-spec
  {:flake {:coerce :string
           :ref "URI"
           :desc "URI is a path to a Flake, which is passed to `nixos-rebuild
                  --flake URI` as is."
           :default "path:///persist/dots"}
   :target {:ref "[USER@]HOST"
            :desc "Deploy config to HOST."
            :coerce parse-target}})

(defn- default-flake [host]
  (str "path:///persist/dots"
       (some->> host (str "#"))))

(defn command-fn [{:keys [args opts]}]
  (let [rebuild-cmd
        (concat (when-not (:target opts)
                  ["sudo"])
                ["nixos-rebuild"]
                (or args ["switch"])
                ["--flake" (or (:flake opts)
                               (-> opts :target :host
                                   default-flake))]
                (when-some [target (:target opts)]
                  ["--sudo" "--ask-sudo-password"
                   "--target-host" (str-target target)]))]
    (apply println "$" rebuild-cmd)
    (-> (apply p/shell {:continue true} rebuild-cmd)
        :exit
        System/exit)))

(def command
  {:cmds ["rebuild"]
   :desc "Rebuild the system's NixOS configuration"
   :fn command-fn
   :spec command-options-spec})
