#!/usr/bin/guile -s
!#
(use-modules (ice-9 debug) (ice-9 getopt-long) (srfi srfi-2))

(define datadir "../common/")
(load (string-append datadir "str.scm"))
(load (string-append datadir "woobus.scm"))
(load (string-append datadir "command.scm"))
(load (string-append datadir "command-compat.scm"))

(define cmdline (command-line))
(define progname (car cmdline))

(define (usage progname)
  (format #t "Usage:  ~A --record filename~%" progname)
  (format #t "or: ~A --play filename~%~%" progname)
  (format #t "  -h, --help     display help screen~%")
  (format #t "  -v, --version  display version information ~%")
  (format #t "	-r,--record  record bus activity to specified file~%")
  (format #t "  p-,--play replay forward commands from specified file on the bus~%~%")
  (format #t "  Report bugs to <inger@altlinux.ru>~%")
  #t)
  
(define (version progname) (format #t "~A version 1.99 ~%" progname) #t)

(define (log-direction logfile addr write-empty write-cmd)
  (let* ((message (read-bus-message))
	 (cmds (message->commands message)))
	(and (null? cmds) (write-empty logfile))
	(for-each (lambda (x) (write-cmd x logfile)) cmds)
	(force-output logfile)
	(write-bus addr message)))

;todo: also duplicate command to bus
(define (log-forward logfile)
  (define (log-command cmd logfile) (write cmd logfile) (newline logfile))
  (define (log-empty logfile) (display ";question:empty" logfile) (newline logfile))
  (log-direction logfile '>> log-empty log-command))

(define (log-backward logfile)
  (define (log-command cmd logfile) (display (format #f ";answer:~S~%" cmd) logfile))
  (define (log-empty logfile) (display ";answer:empty" logfile) (newline logfile))
  (log-direction logfile '<< log-empty log-command))

(define (record filename)
  (define (loop logfile)
    (read-bus-address ('>> (log-forward logfile))
		      ('<< (log-backward logfile)))
    (loop logfile))
  (let ((logfile (open-output-file filename)))
    (loop logfile)
    (close-output-port logfile))
  #t)

(define (play filename)
  (define (read-loop logfile)
    (let ((cmd (read logfile)))
      (cond
	((eof-object? cmd) #t)
	(else
	  (write-bus '>> (commands->message (list cmd)))
	  (read-bus '<<)
	  (read-loop logfile)))))
  (let ((logfile (open-input-file filename)))
    (read-loop logfile)
    (close-input-port logfile)
    (display exit-address)
    (newline))
  #t)

(define option-spec
  '((version (single-char #\v) (value #f))
    (help    (single-char #\h) (value #f))
    (record  (single-char #\r) (value #t))
    (play    (single-char #\p) (value #t))))

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

(and (option-ref options 'help #f) (usage progname) (quit))
(and (option-ref options 'version #f) (version progname) (quit))

(and-let* ((need-record (option-ref options 'record #f)))
	  (record need-record)
	  (quit))
(and-let* ((need-play (option-ref options 'play #f)))
	  (play need-play)
	  (quit))

(usage progname)
(quit)

