/*
 * Copyright (c) 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.servicetag;

import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.TimeZone;
import java.util.UUID;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

// Utility class for com.sun.servicetag package
class Util {
    private static boolean verbose = (System.getProperty("servicetag.verbose") != null);
    private static String jrepath = null;
    private static final String REGKEY_TAIL =
        "microsoft\\windows\\currentversion\\app paths\\stclient.exe";
    private static final String STCLIENT_TAIL =  "sun\\servicetag\\stclient.exe";
    private static final String WIN32_STCLIENT =
        "c:\\Program Files (x86)\\" + STCLIENT_TAIL;

    // for debugging and tracing
    static boolean isVerbose() {
        return verbose;
    }

    /**
     * Gets the pathname of JRE in the running platform
     * This can be a JDK or JRE.
     */
    static synchronized String getJrePath() {
        if (jrepath == null) {
            // Determine the JRE path by checking the existence of
            // <HOME>/jre/lib and <HOME>/lib.
            String javaHome = System.getProperty("java.home");
            jrepath = javaHome + File.separator + "jre";
            File f = new File(jrepath, "lib");
            if (!f.exists()) {
                // java.home usually points to the JRE path
                jrepath = javaHome;
            }
        }
        return jrepath;
    }

    /**
     * Tests if the running platform is a JDK.
     */
    static boolean isJdk() {
        // <HOME>/jre exists which implies it's a JDK
        return getJrePath().endsWith(File.separator + "jre");
    }

    /**
     * Generates the URN string of "urn:st" namespace
     */
    static String generateURN() {
        return "urn:st:" + UUID.randomUUID().toString();
    }

    static int getIntValue(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("\"" + value + "\"" +
                " expected to be an integer");
        }
    }

    /**
     * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT.
     * @param timestamp Date
     * @return a string representation of the timestamp
     *         in the YYYY-MM-dd HH:mm:ss GMT format.
     */
    static String formatTimestamp(Date timestamp) {
        if (timestamp == null) {
            return "[No timestamp]";
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        return df.format(timestamp);
    }

    /**
     * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format.
     * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format.
     * @return Date
     */
    static Date parseTimestamp(String timestamp) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        try {
            return df.parse(timestamp);
        } catch (ParseException e) {
            // should not reach here
            e.printStackTrace();
            return new Date();
        }
    }

    static String commandOutput(Process p) throws IOException {
        Reader r = null;
        Reader err = null;
        try {
            r = new InputStreamReader(p.getInputStream());
            err = new InputStreamReader(p.getErrorStream());
            String output = commandOutput(r);
            String errorMsg = commandOutput(err);
            p.waitFor();
            return output + errorMsg.trim();
        } catch (InterruptedException e) {
            if (isVerbose()) {
                e.printStackTrace();
            }
            return e.getMessage();
        } finally {
            try {
                if (r != null) {
                    r.close();
                }
            } finally {
                if (err != null) {
                    err.close();
                }
            }
        }
    }

    static String commandOutput(Reader r) throws IOException {
        StringBuilder sb = new StringBuilder();
        int c;
        while ((c = r.read()) > 0) {
            if (c != '\r') {
                sb.append((char) c);
            }
        }
        return sb.toString();
    }

    static int getJdkVersion() {
        parseVersion();
        return jdkVersion;
    }

    static int getUpdateVersion() {
        parseVersion();
        return jdkUpdate;
    }

    private static int jdkVersion = 0;
    private static int jdkUpdate = 0;
    private static synchronized void parseVersion() {
        if (jdkVersion > 0) {
            return;
        }

        // parse java.runtime.version
        // valid format of the version string is:
        // n.n.n[_uu[c]][-<identifer>]-bxx
        String cs = System.getProperty("java.runtime.version");
        if (cs.length() >= 5 &&
            Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
            Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
            Character.isDigit(cs.charAt(4))) {
            jdkVersion = Character.digit(cs.charAt(2), 10);
            cs = cs.substring(5, cs.length());
            if (cs.charAt(0) == '_' && cs.length() >= 3 &&
                Character.isDigit(cs.charAt(1)) &&
                Character.isDigit(cs.charAt(2))) {
                int nextChar = 3;
                try {
                    String uu = cs.substring(1, 3);
                    jdkUpdate = Integer.valueOf(uu).intValue();
                } catch (NumberFormatException e) {
                    // not conforming to the naming convention
                    return;
                }
            }
        } else {
            throw new InternalError("Invalid java.runtime.version" + cs);
        }
    }

    /**
     * Returns this java string as a null-terminated byte array
     */
    private static byte[] stringToByteArray(String str) {
        return (str + "\u0000").getBytes();
    }

    /**
     * Converts a null-terminated byte array to java string
     */
    private static String byteArrayToString(byte[] array) {
        return new String(array, 0, array.length -1);
    }

    /**
     * Gets the stclient path using a well known location from
     * the Windows platform Registry, ensuring the path returned
     * by the registry is really the one we are looking for,
     * otherwise it will return null.
     */
    private static File getWindowsStClientFile(boolean wow64) {
        File out = null;
        String regKey = (wow64 == true)
            ? "software\\Wow6432Node\\" + REGKEY_TAIL
            : "software\\" + REGKEY_TAIL;
        String keyName = "" ; // use the default  key
        String path = getRegistryKey(regKey, keyName);
        if (path != null
                && (new File(path)).exists()
                && path.toLowerCase().endsWith(STCLIENT_TAIL.toLowerCase())) {
            out = new File(path);
        }
        if (isVerbose()) {
            System.out.println("stclient=" + out);
        }
        return out;
    }

    /**
     * Finds a stclient in 32 and 64 bit environments, first by querying
     * the windows registry, if not then get the well known paths for
     * 64bit see http://support.microsoft.com/kb/896459
     */

    static File getWindowsStClientFile() {
        File stclient = null;
        if (System.getProperty("os.arch").equals("x86")) {
            // try to get the default entry
            stclient = getWindowsStClientFile(false);
            if (stclient != null) {
                return stclient;
            }
        } else { // we are on 64-bit system
            // try the wow64 area
            stclient = getWindowsStClientFile(true);
            if (stclient != null) {
                return stclient;
            }
            // try the default hard coded path, maybe wow64 registry is missing
            stclient = new File(WIN32_STCLIENT);
            if (stclient.canExecute()) {
                if (isVerbose()) {
                    System.out.println("stclient(default)=" + stclient);
                }
                return stclient;
            }
        }
        if (isVerbose()) {
            System.out.println("stclient not found");
        }
        return null;
    }

    /**
     * This uses reflection to access a private java windows registry
     * interface, any changes to that Class must be appropriately adjusted.
     * Returns a null if unsuccessful.
     */
    private static String getRegistryKey(String regKey, String keyName) {
        String out = null;
        try {
            Class<?> clazz = Class.forName("java.util.prefs.WindowsPreferences");

            // Get the registry methods
            Method winRegOpenKeyM = clazz.getDeclaredMethod("WindowsRegOpenKey",
                    int.class, byte[].class, int.class);
            winRegOpenKeyM.setAccessible(true);

            Method winRegCloseKeyM = clazz.getDeclaredMethod("WindowsRegCloseKey",
                    int.class);
            winRegCloseKeyM.setAccessible(true);

            Method winRegQueryValueM = clazz.getDeclaredMethod("WindowsRegQueryValueEx",
                    int.class, byte[].class);
            winRegQueryValueM.setAccessible(true);

            // Get all the constants we need
            int HKLM = getValueFromStaticField("HKEY_LOCAL_MACHINE", clazz);
            int KEY_READ = getValueFromStaticField("KEY_READ", clazz);
            int ERROR_CODE = getValueFromStaticField("ERROR_CODE", clazz);
            int NATIVE_HANDLE = getValueFromStaticField("NATIVE_HANDLE", clazz);
            int ERROR_SUCCESS = getValueFromStaticField("ERROR_SUCCESS", clazz);

            // Convert keys
            byte[] reg = stringToByteArray(regKey);
            byte[] key = stringToByteArray(keyName);

            // Open the registry
            int[] result = (int[]) winRegOpenKeyM.invoke(null, HKLM, reg, KEY_READ);

            if (result[ERROR_CODE] == ERROR_SUCCESS) {
                byte[] stvalue = (byte[]) winRegQueryValueM.invoke(null,
                    result[NATIVE_HANDLE], key);
                out = byteArrayToString(stvalue);
                winRegCloseKeyM.invoke(null, result[NATIVE_HANDLE]);
            }
        } catch (Exception ex) {
            if (isVerbose()) {
                ex.printStackTrace();
            }
        }
        return out;
    }

    private static int getValueFromStaticField(String fldName, Class<?> klass) throws Exception {
        Field f = klass.getDeclaredField(fldName);
        f.setAccessible(true);
        return f.getInt(null);
    }
}
