#lang racket/base

(require
  "stored-objects.rkt"
  "user.rkt"
  ; Formatting
  (prefix-in scrib: scribble/reader)
  )

(provide
  ; Accessors
  media-name media-file media-type media-author media-date media-licence media-public?
  ; Operations
  new-media update-media remove-media
  get-media-by-name get-media-by-file get-all-medias get-public-medias
  ; Init repo
  media-init-repository
  )

; Media metadata structure
(stored-class notepadmedia
  (name : string?) ; Name of the media, used as shortcut in notes (@media[]{}).
  (file : string?) ; file path of the media
  (type : string?) ; type of media
  (author : integer?) ; author of last update, id of user
  (date : integer?) ; date of last update
  (licence : string?) ; Licence of the media
  (public : boolean?) ; Media publicly listed ?
  )

; Repo initialization
(define (media-init-repository repo)
  (init-repository repo
    notepadmedia))

; Accessors
(define media-name notepadmedia-name)
(define media-file notepadmedia-file)
(define media-type notepadmedia-type)
(define (media-author nt)
  (define author (get-user-by-id (notepadmedia-author nt)))
  (and author (user-pseudo author)))
(define (media-date nt)
  (define dt (seconds->date (notepadmedia-date nt)))
  (define (add-zero x)
    (if (< x 10)
        (string-append "0" (number->string x))
        x))
  (format "~a-~a-~a"
    (date-year dt)
    (add-zero (date-month dt))
    (add-zero (date-day dt))))
(define media-licence notepadmedia-licence)
(define media-public? notepadmedia-public)

; Media Operations

; New media
(define (new-media
          #:name name
          #:file file
          #:type type
          #:author author
          #:licence (licence #f)
          #:public? (public? #f))
  (within-transaction (class-repository notepadmedia)
    (define md (instanciate notepadmedia))
    (set-notepadmedia-name! md name)
    (set-notepadmedia-file! md file)
    (set-notepadmedia-type! md type)
    (set-notepadmedia-author! md (instance-identifier author))
    (set-notepadmedia-date! md (current-seconds))
    (set-notepadmedia-licence! md licence)
    (set-notepadmedia-public! md public?)
    (save-instance md)
    md))

; Update media. If md is #f, create a new media.
(define (update-media md
          #:name name
          #:file file
          #:type type
          #:author author
          #:licence (licence #f)
          #:public? (public? #f)
          )
  (within-transaction (class-repository notepadmedia)
    (define new-md (or md (instanciate notepadmedia)))
    (set-notepadmedia-name! new-md name)
    (set-notepadmedia-file! new-md file)
    (set-notepadmedia-type! new-md type)
    (set-notepadmedia-author! new-md (instance-identifier author))
    (set-notepadmedia-date! new-md (current-seconds))
    (set-notepadmedia-licence! new-md licence)
    (set-notepadmedia-public! new-md public?)
    (save-instance new-md)
    new-md))

; Remove a media
(define (remove-media md)
  (within-transaction (class-repository notepadmedia)
    ; Remove media
    (delete-instance md)))

; Find by name
(define (get-media-by-name name)
  (define medias (find-instances notepadmedia `((name . ,name))))
  (and (not (null? medias))
       (car medias)))

; Find by file
(define (get-media-by-file file)
  (define medias (find-instances notepadmedia `((file . ,file))))
  (and (not (null? medias))
       (car medias)))

; Get all medias
(define (get-all-medias)
  (list-instances notepadmedia))

; Get all public medias
(define (get-public-medias)
  (find-instances notepadmedia '((public . #t))))
