/* java.util.VMTimeZone
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;

import gnu.classpath.Configuration;
import gnu.classpath.SystemProperties;
import gnu.java.util.ZoneInfo;
import java.util.TimeZone;

import java.io.*;

/**
 *
 */
final class VMTimeZone
{
  static
  {
    if (Configuration.INIT_LOAD_LIBRARY)
      {
        System.loadLibrary("javautil");
      }
  }

  /**
   * This method returns a time zone id string which is in the form
   * (standard zone name) or (standard zone name)(GMT offset) or
   * (standard zone name)(GMT offset)(daylight time zone name).  The
   * GMT offset can be in seconds, or where it is evenly divisible by
   * 3600, then it can be in hours.  The offset must be the time to
   * add to the local time to get GMT.  If a offset is given and the
   * time zone observes daylight saving then the (daylight time zone
   * name) must also be given (otherwise it is assumed the time zone
   * does not observe any daylight savings).
   * <p>
   * The result of this method is given to the method
   * TimeZone.getDefaultTimeZone(String) which tries to map the time
   * zone id to a known TimeZone.  See that method on how the returned
   * String is mapped to a real TimeZone object.
   * <p>
   * The reference implementation which is made for GNU/Posix like
   * systems calls <code>System.getenv("TZ")</code>,
   * <code>readTimeZoneFile("/etc/timezone")</code>,
   * <code>ZoneInfo.readTZFile((String)null, "/etc/localtime")</code>
   * and finally <code>getSystemTimeZoneId()</code> till a supported
   * TimeZone is found through
   * <code>TimeZone.getDefaultTimeZone(String)</code>.
   * If every method fails <code>null</code> is returned (which means
   * the TimeZone code will fall back on GMT as default time zone).
   * <p>
   * Note that this method is called inside a
   * <code>AccessController.doPrivileged()</code> block and runs with
   * the priviliges of the java.util system classes.  It will only be
   * called when the default time zone is not yet set, the system
   * property user.timezone isn't set and it is requested for the
   * first time.
   */
  static TimeZone getDefaultTimeZoneId()
  {
    TimeZone zone = null;

    // See if TZ environment variable is set and accessible.
    String tzid = System.getenv("TZ");
    if (tzid != null && !tzid.equals(""))
      zone = TimeZone.getDefaultTimeZone(tzid);

    // Try to parse /etc/timezone.
    if (zone == null)
      {
        tzid = readTimeZoneFile("/etc/timezone");
        if (tzid != null && !tzid.equals(""))
          zone = TimeZone.getDefaultTimeZone(tzid);
      }

    // Try to parse /etc/localtime
    if (zone == null)
      {
        zone = ZoneInfo.readTZFile((String) null, "/etc/localtime");
        if (zone != null)
          {
            // Try to find a more suitable ID for the /etc/localtime
            // timezone.
            // Sometimes /etc/localtime is a symlink to some
            // /usr/share/zoneinfo/ file.
            String id = null;
            try
              {
                id = new File("/etc/localtime").getCanonicalPath();
                if (id != null)
                  {
                    String zoneinfo_dir
                      = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir");
                    if (zoneinfo_dir != null)
                      zoneinfo_dir
                        = new File(zoneinfo_dir
                                   + File.separatorChar).getCanonicalPath();
                    if (zoneinfo_dir != null && id.startsWith(zoneinfo_dir))
                      {
                        int pos = zoneinfo_dir.length();
                        while (pos < id.length()
                               && id.charAt(pos) == File.separatorChar)
                          pos++;
                        if (pos < id.length())
                          id = id.substring(pos);
                        else
                          id = null;
                      }
                    else
                      id = null;
                  }
              }
            catch (IOException ioe)
              {
                id = null;
              }

            if (id == null)
              id = readSysconfigClockFile("/etc/sysconfig/clock");

            if (id != null)
              zone.setID(id);
          }
      }

    // Try some system specific way
    if (zone == null)
      {
        tzid = getSystemTimeZoneId();
        if (tzid != null && !tzid.equals(""))
          zone = TimeZone.getDefaultTimeZone(tzid);
      }

    return zone;
  }

  /**
   * Tries to read the time zone name from a file. Only the first
   * consecutive letters, digits, slashes, dashes and underscores are
   * read from the file. If the file cannot be read or an IOException
   * occurs null is returned.
   * <p>
   * The /etc/timezone file is not standard, but a lot of systems have
   * it. If it exist the first line always contains a string
   * describing the timezone of the host of domain. Some systems
   * contain a /etc/TIMEZONE file which is used to set the TZ
   * environment variable (which is checked before /etc/timezone is
   * read).
   */
  private static String readTimeZoneFile(String file)
  {
    File f = new File(file);
    if (!f.exists())
      return null;

    InputStreamReader isr = null;
    try
      {
        FileInputStream fis = new FileInputStream(f);
        BufferedInputStream bis = new BufferedInputStream(fis);
        isr = new InputStreamReader(bis);

        StringBuffer sb = new StringBuffer();
        int i = isr.read();
        while (i != -1)
          {
            char c = (char) i;
            if (Character.isLetter(c) || Character.isDigit(c)
                || c == '/' || c == '-' || c == '_')
              {
                sb.append(c);
                i = isr.read();
              }
            else
              break;
          }
        return sb.toString();
      }
    catch (IOException ioe)
      {
        // Parse error, not a proper tzfile.
        return null;
      }
    finally
      {
        try
          {
            if (isr != null)
              isr.close();
          }
        catch (IOException ioe)
          {
            // Error while close, nothing we can do.
          }
      }
  }

  /**
   * Tries to read the time zone name from a file.
   * If the file cannot be read or an IOException occurs null is returned.
   * <p>
   * The /etc/sysconfig/clock file is not standard, but a lot of systems
   * have it. The file is included by shell scripts and the timezone
   * name is defined in ZONE variable.
   * This routine should grok it with or without quotes:
   * ZONE=America/New_York
   * or
   * ZONE="Europe/London"
   */
  private static String readSysconfigClockFile(String file)
  {
    BufferedReader br = null;
    try
      {
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        br = new BufferedReader(new InputStreamReader(bis));

        for (String line = br.readLine(); line != null; line = br.readLine())
          {
            line = line.trim();
            if (line.length() < 8 || !line.startsWith("ZONE="))
              continue;
            int posstart = 6;
            int posend;
            if (line.charAt(5) == '"')
              posend = line.indexOf('"', 6);
            else if (line.charAt(5) == '\'')
              posend = line.indexOf('\'', 6);
            else
              {
                posstart = 5;
                posend = line.length();
              }
            if (posend < 0)
              return null;
            return line.substring(posstart, posend);
          }
        return null;
      }
    catch (IOException ioe)
      {
        // Parse error, not a proper tzfile.
        return null;
      }
    finally
      {
        try
          {
            if (br != null)
              br.close();
          }
        catch (IOException ioe)
          {
            // Error while close, nothing we can do.
          }
      }
  }

  /**
   * Tries to get the system time zone id through native code.
   */
  private static native String getSystemTimeZoneId();
}
