#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#

#|
A command-line interface for cl-project:make-project.
|#

(ql:quickload '(:uiop :alexandria) :silent t)

(import 'alexandria:starts-with-subseq)
(import 'alexandria:ensure-list)

(defun help ()
  (format t "~&Usage:
    make-project /home/user/common-lisp/sample --name sample --description \"sample project.\" --author \"Your name\" --license LLGPL --depends-on alexandria split-sequence~%"))

(defun terminate (&optional message args)
  (when message
    (format *error-output* "~&Error: ~A~%"
            (apply #'format nil (princ-to-string message) (ensure-list args))))
  (uiop:quit -1))

(defun parse-args (args)
  (flet ((keyp (string)
           (starts-with-subseq "--" string))
         (parse-value (value)
           (or (ignore-errors
                (let ((read-value (read-from-string value)))
                  (if (and (symbolp read-value)
                           (not (keywordp read-value)))
                      value
                      read-value)))
               value)))
    (let ((path (pop args)))
      (when (starts-with-subseq "--" path)
        (terminate "No path given."))
      (cons (pathname path)
            (loop for index from 0 below (length args)
                  for first = (elt args index)
                  for rest = (subseq args (incf index))
                  for key = (or (when (not (keyp first))
                                  (terminate "Invalid option: ~S" first))
                                (intern (string-upcase (subseq first 2)) :keyword))
                  for value = (if (eql key :depends-on)
                                  (loop for (item . rest) on rest
                                        collecting item
                                        until (keyp (car rest))
                                        do (incf index))
                                  (parse-value (car rest)))
                  nconc (list key (parse-value value)))))))

(defun main (&rest args)
  (unless args
    (help)
    (terminate))

  (ql:quickload :cl-project :silent t)

  (apply (intern (string :make-project) :cl-project) (parse-args args)))
