/*
 * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "TimeZone_md.h"

#define VALUE_UNKNOWN           0
#define VALUE_KEY               1
#define VALUE_MAPID             2
#define VALUE_GMTOFFSET         3

#define MAX_ZONE_CHAR           256
#define MAX_MAPID_LENGTH        32

#define NT_TZ_KEY               "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"
#define WIN_TZ_KEY              "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones"
#define WIN_CURRENT_TZ_KEY      "System\\CurrentControlSet\\Control\\TimeZoneInformation"

typedef struct _TziValue {
    LONG        bias;
    LONG        stdBias;
    LONG        dstBias;
    SYSTEMTIME  stdDate;
    SYSTEMTIME  dstDate;
} TziValue;

/*
 * Registry key names
 */
static void *keyNames[] = {
    (void *) L"StandardName",
    (void *) "StandardName",
    (void *) L"Std",
    (void *) "Std"
};

/*
 * Indices to keyNames[]
 */
#define STANDARD_NAME           0
#define STD_NAME                2

static int isNT = FALSE;        /* TRUE if it is NT. */

/*
 * Calls RegQueryValueEx() to get the value for the specified key. If
 * the platform is NT, 2000 or XP, it calls the Unicode
 * version. Otherwise, it calls the ANSI version and converts the
 * value to Unicode. In this case, it assumes that the current ANSI
 * Code Page is the same as the native platform code page (e.g., Code
 * Page 932 for the Japanese Windows systems.
 *
 * `keyIndex' is an index value to the keyNames in Unicode
 * (WCHAR). `keyIndex' + 1 points to its ANSI value.
 *
 * Returns the status value. ERROR_SUCCESS if succeeded, a
 * non-ERROR_SUCCESS value otherwise.
 */
static LONG
getValueInRegistry(HKEY hKey,
                   int keyIndex,
                   LPDWORD typePtr,
                   LPBYTE buf,
                   LPDWORD bufLengthPtr)
{
    LONG ret;
    DWORD bufLength = *bufLengthPtr;
    char val[MAX_ZONE_CHAR];
    DWORD valSize;
    int len;

    *typePtr = 0;
    if (isNT) {
        ret = RegQueryValueExW(hKey, (WCHAR *) keyNames[keyIndex], NULL,
                               typePtr, buf, bufLengthPtr);
        if (ret == ERROR_SUCCESS && *typePtr == REG_SZ) {
            return ret;
        }
    }

    valSize = sizeof(val);
    ret = RegQueryValueExA(hKey, (char *) keyNames[keyIndex + 1], NULL,
                           typePtr, val, &valSize);
    if (ret != ERROR_SUCCESS) {
        return ret;
    }
    if (*typePtr != REG_SZ) {
        return ERROR_BADKEY;
    }

    len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
                              (LPCSTR) val, -1,
                              (LPWSTR) buf, bufLength/sizeof(WCHAR));
    if (len <= 0) {
        return ERROR_BADKEY;
    }
    return ERROR_SUCCESS;
}

/*
 * Produces custom name "GMT+hh:mm" from the given bias in buffer.
 */
static void customZoneName(LONG bias, char *buffer) {
    LONG gmtOffset;
    int sign;

    if (bias > 0) {
        gmtOffset = bias;
        sign = -1;
    } else {
        gmtOffset = -bias;
        sign = 1;
    }
    if (gmtOffset != 0) {
        sprintf(buffer, "GMT%c%02d:%02d",
                ((sign >= 0) ? '+' : '-'),
                gmtOffset / 60,
                gmtOffset % 60);
    } else {
        strcpy(buffer, "GMT");
    }
}

/*
 * Gets the current time zone entry in the "Time Zones" registry.
 */
static int getWinTimeZone(char *winZoneName, char *winMapID)
{
    TIME_ZONE_INFORMATION tzi;
    OSVERSIONINFO ver;
    int onlyMapID;
    HANDLE hKey = NULL, hSubKey = NULL;
    LONG ret;
    DWORD nSubKeys, i;
    ULONG valueType;
    TCHAR subKeyName[MAX_ZONE_CHAR];
    TCHAR szValue[MAX_ZONE_CHAR];
    WCHAR stdNameInReg[MAX_ZONE_CHAR];
    TziValue tempTzi;
    WCHAR *stdNamePtr = tzi.StandardName;
    DWORD valueSize;
    DWORD timeType;

    /*
     * Get the current time zone setting of the platform.
     */
    timeType = GetTimeZoneInformation(&tzi);
    if (timeType == TIME_ZONE_ID_INVALID) {
        goto err;
    }

    /*
     * Determine if this is an NT system.
     */
    ver.dwOSVersionInfoSize = sizeof(ver);
    GetVersionEx(&ver);
    isNT = ver.dwPlatformId == VER_PLATFORM_WIN32_NT;

    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
                       KEY_READ, (PHKEY)&hKey);
    if (ret == ERROR_SUCCESS) {
        DWORD val;
        DWORD bufSize;

        /*
         * Determine if auto-daylight time adjustment is turned off.
         */
        valueType = 0;
        bufSize = sizeof(val);
        ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet",
                               NULL, &valueType, (LPBYTE) &val, &bufSize);
        /*
         * Vista uses the different key name.
         */
        if (ret != ERROR_SUCCESS) {
          bufSize = sizeof(val);
            ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
                                   NULL, &valueType, (LPBYTE) &val, &bufSize);
        }
        if (ret == ERROR_SUCCESS) {
            if (val == 1) {
                (void) RegCloseKey(hKey);
                customZoneName(tzi.Bias, winZoneName);
                return VALUE_GMTOFFSET;
            }
        }

        /*
         * Vista has the key for the current "Time Zones" entry.
         */
        if (isNT && ver.dwMajorVersion >= 6) {
            valueType = 0;
            bufSize = MAX_ZONE_CHAR;
            ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL,
                                   &valueType, (LPBYTE) winZoneName, &bufSize);
            if (ret != ERROR_SUCCESS) {
                goto err;
            }
            (void) RegCloseKey(hKey);
            return VALUE_KEY;
        }

        /*
         * Win32 problem: If the length of the standard time name is equal
         * to (or probably longer than) 32 in the registry,
         * GetTimeZoneInformation() on NT returns a null string as its
         * standard time name. We need to work around this problem by
         * getting the same information from the TimeZoneInformation
         * registry. The function on Win98 seems to return its key name.
         * We can't do anything in that case.
         */
        if (tzi.StandardName[0] == 0) {
            bufSize = sizeof(stdNameInReg);
            ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType,
                                     (LPBYTE) stdNameInReg, &bufSize);
            if (ret != ERROR_SUCCESS) {
                goto err;
            }
            stdNamePtr = stdNameInReg;
        }
        (void) RegCloseKey(hKey);
    }

    /*
     * Open the "Time Zones" registry.
     */
    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NT_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey);
    if (ret != ERROR_SUCCESS) {
        ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey);
        /*
         * If both failed, then give up.
         */
        if (ret != ERROR_SUCCESS) {
            return VALUE_UNKNOWN;
        }
    }

    /*
     * Get the number of subkeys of the "Time Zones" registry for
     * enumeration.
     */
    ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, &nSubKeys,
                          NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    if (ret != ERROR_SUCCESS) {
        goto err;
    }

    /*
     * Compare to the "Std" value of each subkey and find the entry that
     * matches the current control panel setting.
     */
    onlyMapID = 0;
    for (i = 0; i < nSubKeys; ++i) {
        DWORD size = sizeof(subKeyName);
        ret = RegEnumKeyEx(hKey, i, subKeyName, &size, NULL, NULL, NULL, NULL);
        if (ret != ERROR_SUCCESS) {
            goto err;
        }
        ret = RegOpenKeyEx(hKey, subKeyName, 0, KEY_READ, (PHKEY)&hSubKey);
        if (ret != ERROR_SUCCESS) {
            goto err;
        }

        size = sizeof(szValue);
        ret = getValueInRegistry(hSubKey, STD_NAME, &valueType,
                                 szValue, &size);
        if (ret != ERROR_SUCCESS) {
            /*
             * NT 4.0 SP3 fails here since it doesn't have the "Std"
             * entry in the Time Zones registry.
             */
            RegCloseKey(hSubKey);
            onlyMapID = 1;
            ret = RegOpenKeyExW(hKey, stdNamePtr, 0, KEY_READ, (PHKEY)&hSubKey);
            if (ret != ERROR_SUCCESS) {
                goto err;
            }
            break;
        }

        if (wcscmp((WCHAR *)szValue, stdNamePtr) == 0) {
            /*
             * Some localized Win32 platforms use a same name to
             * different time zones. So, we can't rely only on the name
             * here. We need to check GMT offsets and transition dates
             * to make sure it's the registry of the current time
             * zone.
             */
            DWORD tziValueSize = sizeof(tempTzi);
            ret = RegQueryValueEx(hSubKey, "TZI", NULL, &valueType,
                                  (unsigned char *) &tempTzi, &tziValueSize);
            if (ret == ERROR_SUCCESS) {
                if ((tzi.Bias != tempTzi.bias) ||
                    (memcmp((const void *) &tzi.StandardDate,
                            (const void *) &tempTzi.stdDate,
                            sizeof(SYSTEMTIME)) != 0)) {
                        goto out;
                }

                if (tzi.DaylightBias != 0) {
                    if ((tzi.DaylightBias != tempTzi.dstBias) ||
                        (memcmp((const void *) &tzi.DaylightDate,
                                (const void *) &tempTzi.dstDate,
                                sizeof(SYSTEMTIME)) != 0)) {
                        goto out;
                    }
                }
            }

            /*
             * found matched record, terminate search
             */
            strcpy(winZoneName, subKeyName);
            break;
        }
    out:
        (void) RegCloseKey(hSubKey);
    }

    /*
     * Get the "MapID" value of the registry to be able to eliminate
     * duplicated key names later.
     */
    valueSize = MAX_MAPID_LENGTH;
    ret = RegQueryValueExA(hSubKey, "MapID", NULL, &valueType, winMapID, &valueSize);
    (void) RegCloseKey(hSubKey);
    (void) RegCloseKey(hKey);

    if (ret != ERROR_SUCCESS) {
        /*
         * Vista doesn't have mapID. VALUE_UNKNOWN should be returned
         * only for Windows NT.
         */
        if (onlyMapID == 1) {
            return VALUE_UNKNOWN;
        }
    }

    return VALUE_KEY;

 err:
    if (hKey != NULL) {
        (void) RegCloseKey(hKey);
    }
    return VALUE_UNKNOWN;
}

/*
 * The mapping table file name.
 */
#define MAPPINGS_FILE "\\lib\\tzmappings"

/*
 * Index values for the mapping table.
 */
#define TZ_WIN_NAME     0
#define TZ_MAPID        1
#define TZ_REGION       2
#define TZ_JAVA_NAME    3

#define TZ_NITEMS       4       /* number of items (fields) */

/*
 * Looks up the mapping table (tzmappings) and returns a Java time
 * zone ID (e.g., "America/Los_Angeles") if found. Otherwise, NULL is
 * returned.
 *
 * value_type is one of the following values:
 *      VALUE_KEY for exact key matching
 *      VALUE_MAPID for MapID and country-based mapping (this is
 *      required for the old Windows, such as NT 4.0 SP3).
 */
static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName,
                         char *mapID, const char *country)
{
    int line;
    int IDmatched = 0;
    FILE *fp;
    char *javaTZName = NULL;
    char *items[TZ_NITEMS];
    char mapFileName[_MAX_PATH + 1];
    char lineBuffer[MAX_ZONE_CHAR * 4];
    char bestMatch[MAX_ZONE_CHAR];
    int noMapID = *mapID == '\0';       /* no mapID on Vista */

    bestMatch[0] = '\0';

    strcpy(mapFileName, java_home_dir);
    strcat(mapFileName, MAPPINGS_FILE);

    if ((fp = fopen(mapFileName, "r")) == NULL) {
        jio_fprintf(stderr, "can't open %s.\n", mapFileName);
        return NULL;
    }

    line = 0;
    while (fgets(lineBuffer, sizeof(lineBuffer), fp) != NULL) {
        char *start, *idx, *endp;
        int itemIndex = 0;

        line++;
        start = idx = lineBuffer;
        endp = &lineBuffer[sizeof(lineBuffer)];

        /*
         * Ignore comment and blank lines.
         */
        if (*idx == '#' || *idx == '\n') {
            continue;
        }

        for (itemIndex = 0; itemIndex < TZ_NITEMS; itemIndex++) {
            items[itemIndex] = start;
            while (*idx && *idx != ':') {
                if (++idx >= endp) {
                    goto illegal_format;
                }
            }
            if (*idx == '\0') {
                goto illegal_format;
            }
            *idx++ = '\0';
            start = idx;
        }

        if (*idx != '\n') {
            goto illegal_format;
        }

        if (noMapID || strcmp(mapID, items[TZ_MAPID]) == 0) {
            /*
             * When there's no mapID, we need to scan items until the
             * exact match is found or the end of data is detected.
             */
            if (!noMapID) {
                IDmatched = 1;
            }
            if (strcmp(items[TZ_WIN_NAME], tzName) == 0) {
                /*
                 * Found the time zone in the mapping table.
                 */
                javaTZName = strdup(items[TZ_JAVA_NAME]);
                break;
            }
            /*
             * Try to find the most likely time zone.
             */
            if (*items[TZ_REGION] == '\0') {
                strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR);
            } else if (country != NULL && strcmp(items[TZ_REGION], country) == 0) {
                if (value_type == VALUE_MAPID) {
                    javaTZName = strdup(items[TZ_JAVA_NAME]);
                    break;
                }
                strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR);
            }
        } else {
            if (IDmatched == 1) {
                /*
                 * No need to look up the mapping table further.
                 */
                break;
            }
        }
    }
    fclose(fp);

    if (javaTZName == NULL && bestMatch[0] != '\0') {
        javaTZName = strdup(bestMatch);
    }
    return javaTZName;

 illegal_format:
    (void) fclose(fp);
    jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", line);
    return NULL;
}

/*
 * Detects the platform time zone which maps to a Java time zone ID.
 */
char *findJavaTZ_md(const char *java_home_dir, const char *country)
{
    char winZoneName[MAX_ZONE_CHAR];
    char winMapID[MAX_MAPID_LENGTH];
    char *std_timezone = NULL;
    int  result;

    winMapID[0] = 0;
    result = getWinTimeZone(winZoneName, winMapID);

    if (result != VALUE_UNKNOWN) {
        if (result == VALUE_GMTOFFSET) {
            std_timezone = strdup(winZoneName);
        } else {
            std_timezone = matchJavaTZ(java_home_dir, result,
                                       winZoneName, winMapID, country);
        }
    }

    return std_timezone;
}

/**
 * Returns a GMT-offset-based time zone ID. On Win32, it always return
 * NULL since the fall back is performed in getWinTimeZone().
 */
char *
getGMTOffsetID()
{
    return NULL;
}
