#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
;; yc 10/19/2009 - use depend.ss for centralized dependency

(require "base.ss" 

(define zoneinfo-files '("africa"

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

(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))

;; #|
;; 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)
           (iterate (cdr kvs) (hash-set hash (caar kvs) (cdar kvs))))))
  (define (helper rest out)
    (cond ((null? rest) out)
           (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 (olson-path))) 
  (when (file-exists? (abbr-path))
    (delete-file! (abbr-path)))
  (for-each (lambda (path)
              (let ((zoneinfo (file->zoneinfo path))) 
                (for-each (lambda (kv)
                            (tz->file! (car kv) (cdr kv)))
                           (make-raw-zoneinfo zoneinfo)))))
            (append (map (lambda (file)
                           (build-path dir file))
                    ;; (map olson2-path '("standard"))
  ;; let's handle the pure links...
  (for-each file->links! 
            (map (lambda (file)
                   (build-path dir file)) 

(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!)