
import java.io.*;
import java.util.*;

// usage: java ZoneCompiler <setup file> <top-level directory>
//
// Compile a set of tzfile-formatted files into a single file plus
// an index file.
//
// The compilation is controlled by a setup file, which is provided as a
// command-line argument.  The setup file has the form:
//
// Link <toName> <fromName>
// ...
// <zone filename>
// ...
//
// Note that the links must be declared prior to the zone names.  A
// zone name is a filename relative to the source directory such as
// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
//
// Use the 'zic' command-line tool to convert from flat files
// (e.g., 'africa', 'northamerica') into a suitable source directory
// hierarchy for this tool (e.g., 'data/Africa/Abidjan').
//
// Example:
//     zic -d data tz2007h
//     javac ZoneCompactor.java
//     java ZoneCompactor setup data
//     <produces zoneinfo.dat and zoneinfo.idx>

public class ZoneCompactor {

    // Zone name synonyms
    Map<String,String> links = new HashMap<String,String>();

    // File starting bytes by zone name
    Map<String,Integer> starts = new HashMap<String,Integer>();

    // File lengths by zone name
    Map<String,Integer> lengths = new HashMap<String,Integer>();

    // Raw GMT offsets by zone name
    Map<String,Integer> offsets = new HashMap<String,Integer>();
    int start = 0;

    // Maximum number of characters in a zone name, including '\0' terminator
    private static final int MAXNAME = 40;

    // Concatenate the contents of 'inFile' onto 'out'
    // and return the contents as a byte array.
    private static byte[] copyFile(File inFile, OutputStream out)
        throws Exception {
        byte[] ret = new byte[0];

        InputStream in = new FileInputStream(inFile);
        byte[] buf = new byte[8192];
        while (true) {
            int nbytes = in.read(buf);
            if (nbytes == -1) {
                break;
            }
            out.write(buf, 0, nbytes);

            byte[] nret = new byte[ret.length + nbytes];
            System.arraycopy(ret, 0, nret, 0, ret.length);
            System.arraycopy(buf, 0, nret, ret.length, nbytes);
            ret = nret;
        }
        out.flush();
        return ret;
    }
    
    // Write a 32-bit integer in network byte order
    private void writeInt(OutputStream os, int x) throws IOException {
        os.write((x >> 24) & 0xff);
        os.write((x >> 16) & 0xff);
        os.write((x >>  8) & 0xff);
        os.write( x        & 0xff);
    }

    public ZoneCompactor(String setupFilename, String dirName)
        throws Exception {
        File zoneInfoFile = new File("zoneinfo.dat");
        zoneInfoFile.delete();
        OutputStream zoneInfo = new FileOutputStream(zoneInfoFile);

        BufferedReader rdr = new BufferedReader(new FileReader(setupFilename));
    
        String s;
        while ((s = rdr.readLine()) != null) {
            s = s.trim();
            if (s.startsWith("Link")) {
                StringTokenizer st = new StringTokenizer(s);
                st.nextToken();
                String to = st.nextToken();
                String from = st.nextToken();
                links.put(from, to);
            } else {
                String link = links.get(s);
                if (link == null) {
                    File f = new File(dirName, s);
                    long length = f.length();
                    starts.put(s, new Integer(start));
                    lengths.put(s, new Integer((int)length));

                    start += length;
                    byte[] data = copyFile(f, zoneInfo);

                    TimeZone tz = ZoneInfo.make(s, data);
                    int gmtOffset = tz.getRawOffset();
                    offsets.put(s, new Integer(gmtOffset));
                }
            }
        }
        zoneInfo.close();

        // Fill in fields for links
        Iterator<String> iter = links.keySet().iterator();
        while (iter.hasNext()) {
            String from = iter.next();
            String to = links.get(from);

            starts.put(from, starts.get(to));
            lengths.put(from, lengths.get(to));
            offsets.put(from, offsets.get(to));
        }

        File idxFile = new File("zoneinfo.idx");
        idxFile.delete();
        FileOutputStream idx = new FileOutputStream(idxFile);

        ArrayList<String> l = new ArrayList<String>();
        l.addAll(starts.keySet());
        Collections.sort(l);
        Iterator<String> ziter = l.iterator();
        while (ziter.hasNext()) {
            String zname = ziter.next();
            if (zname.length() >= MAXNAME) {
                System.err.println("Error - zone filename exceeds " +
                                   (MAXNAME - 1) + " characters!");
            }

            byte[] znameBuf = new byte[MAXNAME];
            for (int i = 0; i < zname.length(); i++) {
                znameBuf[i] = (byte)zname.charAt(i);
            }
            idx.write(znameBuf);
            writeInt(idx, starts.get(zname).intValue());
            writeInt(idx, lengths.get(zname).intValue());
            writeInt(idx, offsets.get(zname).intValue());
        }
        idx.close();

        // System.out.println("maxLength = " + maxLength);
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.err.println("usage: java ZoneCompactor <setup> <data dir>");
            System.exit(0);
        }
        new ZoneCompactor(args[0], args[1]);
    }

}
