;;; Dezyne --- Dezyne command line tools
;;;
;;; Copyright © 2017, 2018, 2019 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2019 Rob Wieringa <Rob.Wieringa@verum.com>
;;; Copyright © 2017, 2018 Johri van Eerd <johri.van.eerd@verum.com>
;;;
;;; This file is part of Dezyne.
;;;
;;; Dezyne is free software: you can redistribute it and/or modify it
;;; under the terms of the GNU Affero General Public License as
;;; published by the Free Software Foundation, either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; Dezyne is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public
;;; License along with Dezyne.  If not, see <http://www.gnu.org/licenses/>.
;;;
;;; Commentary:
;;;
;;; Code:

(define-module (dzn command-line)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 getopt-long)
  #:use-module (dzn script)
  #:export (command-line:get
            command:command-line
            dzn:command-line:get
            dzn:debugity
            dzn:multi-opt
            dzn:verbosity
            %locations?
            multi-opt
            EXIT_OTHER_FAILURE))

(define EXIT_OTHER_FAILURE 2)

(define %locations?
  (make-parameter #f))

(define multi-options
  '(import))

(define* (command-line:get option #:optional default)
  (and (> (length (command-line)) 1)
       (let* ((files (option-ref (parse-opts (command-line)) '() '(#f)))
              (file (car files))
              (command (string->symbol file))
              (parse-opts (let ((module (resolve-module `(dzn commands ,command))))
                            (module-ref module 'parse-opts)))
              (options (if command (parse-opts files)
                           (parse-opts (command-line))))
              (multi-opt (lambda (option) (lambda (o) (and (eq? (car o) option) (cdr o))))))
         (if (not (member option multi-options)) (option-ref options option default)
             (filter-map (multi-opt option) options)))))

(define (dzn:options)
  (parse-opts (command-line)))

(define* (dzn:command-line:get option #:optional default)
  (and (> (length (command-line)) 1)
       (let ((options (parse-opts (command-line))))
         (option-ref options option default))))

(define (multi-opt options name)
  (let ((opt? (lambda (o) (and (eq? (car o) name) (cdr o)))))
    (filter-map opt? options)))

(define (dzn:multi-opt name)
  (and (> (length (command-line)) 1)
       (multi-opt (dzn:options) name)))

(define (dzn:debugity)
  (or (and (pair? (command-line))
           (member ((compose basename car command-line))
                   '("dzn" ".dzn-real"))
           (and=> (dzn:multi-opt 'debug) length))
      0))

(define (dzn:verbosity)
  (dzn:multi-opt 'debug))

(define* (command:command-line #:optional (options (dzn:options)))
  (option-ref options '() '()))
