(define (printer-char-quote ch)
  (case ch
    ((#\%) "%%")
    ((#\|) "%|")
    ((#\/) "|")
    (else (string ch))))

(define (printer-char-unquote ch)
  (case ch
    ((#\%) "%")
    ((#\|) "|")
    (else (string ch))))

(define (printer-char-translate ch)
  (if (char=? ch #\|) "/" (string ch)))

(define (printer-string-quote str)
  (string-quote printer-char-quote str))

(define (printer-string-unquote str)
  (string-unquote #\% printer-char-unquote printer-char-translate str))

(define db
  (let* ((db-table
	  (with-input-from-file "/var/cache/printer-drivers/dump"
				(lambda ()
				  (read-fold
				    (lambda (line table)
				      (let* ((sp (string-splitting line #\;))
					     (key (car sp))
					     (handle (hash-get-handle table key))
					     (val (or (and handle (cdr handle)) '())))
					(hash-set! table key (cons  (cons (cadr sp) (caddr sp))
								    val))
					table))
				    (make-hash-table 10)))))
	 (keys (hash-fold (lambda (x y z) (cons x z)) '() db-table)))
    (cons keys db-table)))

(define (read-printers-models vendor table)
  (let ((models (hash-get-handle table vendor)))
    (if models
      (map (lambda (x) (list (printer-string-quote (car x)))) (cdr models))
      '(error "unknown vendor"))))

(define (read-printers-driver vendor model table)
  (let ((models (hash-get-handle table vendor)))
    (if models
      (let ((info (assoc model (cdr models))))
	(if info (list 'id (cdr info))
	  '(error "unknown model")))
      '(error "unknown vendor"))))
	  
(lambda (objects action)
  (cond 
    ((eq? action 'list)
     (case (length objects)
       ((0) (lambda args (map (lambda (x) (list (printer-string-quote x))) (car db))))
       ((1) (lambda args (read-printers-models (printer-string-unquote (car objects)) (cdr db))))
       (else (error-mariner "wrong number of arguments"))))
    ((eq? action 'read)
     (if (= (length objects) 2)
       (lambda args (read-printers-driver (printer-string-unquote (car objects)) 
					  (printer-string-unquote (cadr objects)) (cdr db)))
       (error-mariner "wrong number of arguments")))
    (else (error-mariner "unsupported action for printer_drivers backend"))))


