#lang racket

(require racket/format)

(provide make-challenge add-status (struct-out challenge))

(struct challenge (id description flag input output allowed status err))

; This list is non-exhaustive, you can help by expanding it.
(define never-allow '(read string->symbol))

(define (verify-allowed allowed)
  (define res 
    (map (lambda (sym)
           (define found (member sym never-allow))
           (if found
             (car found)
             '()))
         allowed))
  (flatten res))

(define (make-challenge id description flag input output allowed)
  (define bad-allowed (verify-allowed allowed))
  (cond 
    ((not (null? bad-allowed))
     (error "Error: you allowed a variable in a challenge that may lead to remote code execution: " (~v bad-allowed)))
    ((not (= (length input) (length output)))
     (error "Input and output of a challenge needs to be of the same length"))
    (else
      (challenge id description flag input output allowed #f ""))))

(define (add-status status err c)
  (challenge (challenge-id c)
             (challenge-description c)
             (challenge-flag c)
             (challenge-input c)
             (challenge-output c)
             (challenge-allowed c)
             status
             err))
