#!/usr/bin/guile18 -s
!#
(use-modules (ice-9 getopt-long)
	     (srfi srfi-13)
	     (alterator exit-handler)
	     (alterator common)
	     (alterator plist)
	     (alterator metalterator)
	     (alterator backend meta))

;;; functions

(define *cmdline* (command-line))

(define (cmdline->woo cmdline)
  (and (pair? cmdline)
       (plist? (cdr cmdline))
       (cons (car cmdline)
             (plist-fold (lambda(x y res) (cons* (string->symbol x) y res))
                         '()
                         (cdr cmdline)))))

(define (print-command key cmd)
  (if key
    (let ((result (cond-plistq  (string->symbol key) (cdr cmd) 'not-found)))
      (or (eq? result 'not-found) (format #t "~A~%" result)))
    (begin
      (newline)
      (plist-for-each
	(lambda (x y) (format #t "~A:~A~%" x y))
	(cdr cmd)))))

(define (usage)
  (format #t "Usage:  ~A [-l] [-k name] command~%" program-name)
  (format #t "  -h, --help              display help screen~%")
  (format #t "  -k KEY,--key=KEY        print KEY value only~%")
  (format #t "  -d LEVEL,--debug=LEVEL  turn on debug LEVEL~%")
  (format #t "~%")
  (format #t "  Report bugs to <manowar@altlinux.ru>~%")
  (quit))

(define (cmdline-error reason)
  (format (current-error-port) "~A: ~A~%" program-name reason)
  (exit 1))

(define (catch/message proc)
  (with-throw-handler
    #t
    proc
    (lambda(key . args)
      (format (current-error-port) "Error: ~A~%"
              (string-join (map sure-string
                                (if (list? args)
                                    args
                                    (list args)))
                           ". "))
      (exit 1))))

;;; main code

(define (turn-on-debugging level)
  (backend '() (list 'action "write" 'debug-level level)))

(define option-spec
  '((help  (single-char #\h) (value #f))
    (key   (single-char #\k) (value #t))
    (debug (single-char #\d) (value #t))))

(define options (getopt-long *cmdline* option-spec))

(and (option-ref options 'help #f) (usage))
(and (option-ref options 'debug #f)
     (turn-on-debugging (option-ref options 'debug #f)))

(define *key* (option-ref options 'key #f))
(define *request* (or (cmdline->woo (option-ref options '() '()))
                      (cmdline-error "Wrong query format")))
(with-exit-handler
  (lambda ()
    (catch/message
      (lambda ()
        (let ((cmdlist (meta-cmd (cdr (string-split (car *request*) #\/))
                                 (cdr *request*))))
         (if (eof-object? cmdlist)
             (cmdline-error "unexpected eof from meta backend")
             (for-each
               (lambda(cmd) (print-command *key* cmd))
               cmdlist)))))))
