convert.ss
#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DATE-TZ.plt - provides time-zone-based date calculations
;;
;; Bonzai Lab, LLC.  All rights reserved.
;;
;; released under LGPL.
;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; convert.ss - converts from the read zoneinfo (from reader.ss) into a raw zoneinfo
;;              that'll then be consumed by normalize.ss
;; yc 10/2/2009 - first version

(require "base.ss" (planet bzlib/base) (planet bzlib/file:1:1) scheme/pretty)
;; the first step is to process the zoneinfo...
(define (make-rules rules)
  (make-immutable-hash (map (lambda (kv)
                              (cons (car kv)
                                    (map (lambda (rule)
                                           (apply make-rule rule)) 
                                         (cdr kv))))
                            (if (not rules) '()
                                (cdr rules)))))

(define (make-zones zones rules)
  (make-immutable-hash 
   (map (lambda (kv)
          (cons (car kv)
                (map (lambda (zone)
                       (define (helper offset rule format until)
                         (make-zone-span offset 
                                         (if (number? rule) rule
                                             (hash-ref rules rule #f)) 
                                         format until))
                       (apply helper zone))
                     (cdr kv))))
        (if (not zones) '()
            (cdr zones)))))

(define (make-links zones links)
  (define (helper zones key rest)
    (if (null? rest) 
        zones
        (helper (hash-set zones (car rest) 
                          (hash-ref zones key)) 
                key (cdr rest))))
  (foldl (lambda (link zones)
           (let ((key (car link)) 
                 (links (map car (cdr link))))
             (helper zones key links)))
         zones 
         (if (not links) '()
             (cdr links))))

(define (make-raw-zoneinfo zi)
  (let ((zi (cdr zi)))
    (make-links (make-zones (assoc 'zone zi) (make-rules (assoc 'rule zi)))
                (assoc 'link zi))))

(define (save-zoneinfo-db! zi)
  (call-with-output-atomic-file (build-path (this-expression-source-directory) "zoneinfo.db")
                                (lambda (out)
                                  (pretty-display zi out))))

(provide/contract 
 (make-raw-zoneinfo (-> any/c any))
 (save-zoneinfo-db! (-> any/c any))
 )