;; VarInt encoding and decoding utilities
;; These functions implement variable-length integer encoding commonly used in Protocol Buffers

;; Encode a positive integer into a varint format
(define (encode-varint n)
  (cond ((< n 128)
         ;; Single byte case
         (list n))
        (else
         ;; Recursive case: encode remaining bits and prepend current byte
         (append (encode-varint (arithmetic-shift n -7))
                 (list (bitwise-or (logand n 127) 128))))))

;; Decode a varint from a sequence of bytes
(define (decode-varint bytes)
  (define (decode-helper bytes result shift)
    (if (null? bytes)
        (error "Incomplete varint"))
    (let ((byte (car bytes)))
      (cond ((zero? (bitwise-and byte 128))
             ;; Last byte encountered
             (+ result (arithmetic-shift byte shift)))
            (else
             ;; Continue decoding with next byte
             (decode-helper (cdr bytes)
                          (+ result (arithmetic-shift (logand byte 127) shift))
                          (+ shift 7)))))))
  (decode-helper bytes 0))

;; Helper functions for working with varints
(define (varint-bytes->list bytes)
  (map (lambda (byte) (if (integer? byte) byte (char->integer byte))) bytes))

(define (varint-list->bytes encoded)
  (map char encoded))
;; Example usage
(let ((encoded (encode-varint 16384)))
  (display "Encoded varint: ") (write encoded) (newline)
  (let ((decoded (decode-varint encoded)))
    (display "Decoded value: ") (display decoded) (newline)))