#!/usr/bin/env janet

# CLI tool for building janet projects. Wraps cook.

(import cook)

(def- argpeg
  (peg/compile
    '(* "--" '(some (if-not "=" 1)) (+ (* "=" '(any 1)) -1))))

(defn- local-rule
  [rule]
  (cook/import-rules "./project.janet")
  (cook/do-rule rule))

(defn- help
  []
  (print `
usage: jpm [--key=value, --flag] ... [subcommand] [args] ...

Subcommands are:
  build : build all artifacts
  install (repo) : install artifacts. If a repo is given, install the contents of that
                   git repository, assuming that the repository is a jpm project. If not, build
                   and install the current project.
  uninstall (module) : uninstall a module. If no module is given, uninstall the module
                       defined by the current directory.
  clean : remove any generated files or artifacts
  test : run tests
  deps : install dependencies.
  clear-cache : clear the git cache. Useful for updating dependencies.

Keys are:
  --modpath : The directory to install modules to. Defaults to $JANET_MODPATH or (dyn :syspath)
  --headerpath : The directory containing janet headers. Defaults to $JANET_HEADERPATH.
  --binpath : The directory to install binaries and scripts. Defaults to $JANET_BINPATH.
  --libpath : The directory containing janet C libraries (libjanet.*). Defaults to $JANET_LIBPATH.
  --optimize : Optimization level for natives. Defaults to 2.
  --compiler : C compiler to use for natives. Defaults to cc (cl on windows).
  --linker : C linker to use for linking natives. Defaults to cc (link on windows).
  --cflags : Extra compiler flags for native modules.
  --lflags : Extra linker flags for native modules.

Flags are:
  --verbose : Print shell commands as they are executed.
    `))

(defn build
  []
  (local-rule "build"))

(defn clean
  []
  (local-rule "clean"))

(defn install
  [&opt repo]
  (if repo
    (cook/install-git repo)
    (local-rule "install")))

(defn test
  []
  (local-rule "test"))

(defn uninstall
  [&opt what]
  (if what
    (cook/uninstall what)
    (local-rule "uninstall")))

(defn deps
  []
  (local-rule "install-deps"))

(def subcommands
  {"build" build
   "clean" clean
   "install" install
   "test" test
   "help" help
   "deps" deps
   "clear-cache" cook/clear-cache
   "uninstall" uninstall})

(def args (tuple/slice (dyn :args) 1))
(def len (length args))
(var i 0)

# Get flags
(while (< i len)
  (if-let [m (peg/match argpeg (args i))]
    (if (= 2 (length m))
      (let [[key value] m]
        (setdyn (keyword key) value))
      (setdyn (keyword (m 0)) true))
    (break))
  (++ i))

# Run subcommand
(if (= i len)
  (help)
  (do
    (if-let [com (subcommands (args i))]
      (com ;(tuple/slice args (+ i 1)))
      (do
        (print "invalid command " (args i))
        (help)))))
