#lang scheme/base

;; crypto file...
;; we want to pass in an encryption scheme... this does not control the path that is being
;; encrypted.
;; (encrypt-file path) => ;; write over the file?
;; (save-encrypted-file path data) => write the data into the path as encrypted file...
(require (planet bzlib/base) 
         (planet vyzo/crypto) 
         (planet vyzo/crypto/util)

(define (make-input-encrypted-pipe cipher key iv)
  (lambda (port)
    (decrypt cipher key iv)))

(define (make-output-encrypted-pipe cipher key iv)
  (lambda (port)
    (encrypt cipher key iv)))

;; crypto already provided its own pipe mechanism, which would make it hard to combine them together...
;; hmm...
;; how would this work?
;; what I want to do is to be able to supply my own version of the make-pipe function...
(define (open-input-encrypted-port in cipher key iv)
  (make-input-filter-port in #f (make-input-encrypted-pipe cipher key iv)))

(define call-with-input-encrypted-port
  (make-call-with-input-port open-input-encrypted-port in cipher key iv))

(define (open-input-encrypted-file path cipher key iv)
  (open-input-encrypted-port (open-input-file path) cipher key iv))

(define call-with-input-encrypted-file
  (make-call-with-input-port open-input-encrypted-file path cipher key iv))

(define (open-output-encrypted-port out cipher key iv)
  (make-output-filter-port out #f (make-output-encrypted-pipe cipher key iv)))

(define call-with-output-encrypted-port
  (make-call-with-output-port open-output-encrypted-port out cipher key iv))

(define (open-output-encrypted-file path cipher key iv #:exists (exists 'replace))
  (open-output-encrypted-port (open-output-file path #:exists exists) cipher key iv))

(define call-with-output-encrypted-file
  (make-call-with-output-port open-output-encrypted-file path cipher key iv #:exists (exists 'replace)))

 (make-input-encrypted-pipe (-> cipher? bytes? bytes? make-pipe/c))
 (make-output-encrypted-pipe (-> cipher? bytes? bytes? make-pipe/c))
 (open-input-encrypted-port (-> input-port? cipher? bytes? bytes? input-port?))
 (call-with-input-encrypted-port (-> input-port? cipher? bytes? bytes? (-> input-port? any) any))
 (open-input-encrypted-file (-> path-string? cipher? bytes? bytes? input-port?))
 (call-with-input-encrypted-file (-> path-string? cipher? bytes? bytes? (-> input-port? any) any))
 (open-output-encrypted-port (-> output-port? cipher? bytes? bytes? output-port?))
 (call-with-output-encrypted-port (-> output-port? cipher? bytes? bytes? (-> output-port? any) any))
 (open-output-encrypted-file (->* (path-string? cipher? bytes? bytes?)
                                  (#:exists (or/c 'replace 'error))
 (call-with-output-encrypted-file (->* (path-string? cipher? bytes? bytes? (-> output-port? any))
                                       (#:exists (or/c 'replace 'error))

;; maybe? (provide (all-from-out (planet vyzo/crypto) (planet vyzo/crypto/util)))

(require "" "" net/base64 file/gzip file/gunzip)
(define cipher cipher:aes-128)
(define-values (key iv) (generate-key cipher))

 (make-output-filter-port (open-output-file "" #:exists 'replace) 
                          output-gzip-filter ;; gzip 
                          #f ;; encrypted 
                          (make-output-encrypted-pipe cipher key iv)
                          output-base64-filter ;; base64 
 (lambda (out)
   (call-with-input-file ""
     (lambda (in)
       (copy-port in out)))))

 (make-input-filter-port (open-input-file "")
                         input-gzip-filter ;; gzip 
                         #f ;; aes
                         (make-input-encrypted-pipe cipher key iv)
                         input-base64-filter ;; base64 
                         #f )
 (lambda (in)
   (read-bytes 20000 in)))

#|(call-with-input-file ""
  (lambda (in)
    (call-with-output-file ""
      (lambda (out)
         (lambda (out)
            cipher key iv 
            (lambda (out)
               (lambda (out)
                 (copy-port in out))))))))
      #:exists 'replace)))

(call-with-input-file ""
  (lambda (in)
     (lambda (in)
        in cipher key iv
        (lambda (in) 
           (lambda (in)
             (read-bytes 20000 in)))))))))