zic.ss
#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DATE-TZ.plt - provides time-zone-based date calculations
;;
;; Bonzai Lab, LLC.  All rights reserved.
;;
;; released under LGPL.
;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; zic.ss - zoneinfo compiler module.  this is the frontend to convert
;;          the olson database into normalized tz strucures that we can consume
;;          order: 1 - read, 2 - convert, 3 - normalize, 4 - serialize
;; yc 10/2/2009 - first version

(require "base.ss" 
         "util.ss"
         "reader.ss" 
         "convert.ss"
         srfi/19 (planet bzlib/date) 
         (planet bzlib/base)
         (planet bzlib/file:1:1)
         "normalize.ss"
         "serialize.ss"
         ) 

(define zoneinfo-files '("africa"
                         "antarctica"
                         "asia"
                         "australasia"
                         "europe"
                         "northamerica"
                         "southamerica"
                         ))

(define zoneinfo-links-files '("backward"
                               "pacificnew"
                               ))

(define (file->zoneinfo file)
  (define (helper zis) 
    (cons 'zoneinfo 
          (map (lambda (kv)
                 (cons (car kv)
                       (group (cdr kv))))
               (group zis))))
  (helper (call-with-input-file file read-zoneinfo))) 
(trace file->zoneinfo)
(define (files->zoneinfos files) 
  (define (helper zis) 
    (cons 'zoneinfo 
          (map (lambda (kv)
                 (cons (car kv)
                       (group (cdr kv))))
               (group zis))))
  (helper (apply append 
                 (map (lambda (path)
                        (call-with-input-file path read-zoneinfo))
                      files))))

;; #|
;; this is now wrong... because each file might reuse the names for rules!!!....
;; we'll have to rewrite it

(define (hash-merge hash . rest) 
  (define (iterate kvs hash)
    (cond ((null? kvs) hash)
          (else
           (iterate (cdr kvs) (hash-set hash (caar kvs) (cdar kvs))))))
  (define (helper rest out)
    (cond ((null? rest) out)
          (else
           (helper (cdr rest)
                   (iterate (hash-map (car rest) (lambda (k v) (cons k v))) out)))))
  (helper (cons hash rest) (make-immutable-hash '()))) 

(define (compile-zoneinfo! (dir (current-directory))) 
  (for-each (lambda (path)
              (let ((zoneinfo (file->zoneinfo path))) 
                (for-each (lambda (kv)
                            (tz->file! (car kv) (cdr kv)))
                          (raw-zoneinfo->normalized-zoneinfo
                           (make-raw-zoneinfo zoneinfo)))))
            (append (map (lambda (file)
                           (build-path dir file))
                         zoneinfo-files)
                    (map (lambda (file)
                           (build-path (this-expression-source-directory) "olson2" file))
                         '("standard"))
                    ))
  ;; let's handle the pure links...
  (for-each file->links! 
            (map (lambda (file)
                   (build-path dir file)) 
                 zoneinfo-links-files)))

(define (file->links! path)
  (define (helper source destination) 
    (make-directory* (parent-path destination))
    (when (file-exists? source)
      (when (file-exists? destination)
        (delete-file! destination))
      (copy-file source destination)))
  (trace helper)
  (for-each (lambda (link)
              (apply helper (map zone-path link)))
            (map cdr (call-with-input-file path read-zoneinfo))))

(trace file->links!)

;;|#