/*
 * Copyright 2021 Contributors to the Eclipse Foundation.
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.util;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.UnsupportedCharsetException;
import java.rmi.Remote;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

/**
 * Handy class full of static functions.
 */
public final class Utility {

    static final Logger _logger = CULoggerInfo.getLogger();

    private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(Utility.class);

    public static void checkJVMVersion() {
        // do not perform any JVM version checking
    }

    /**
     * Returns true if the given string is null or is empty.
     *
     * @param string The string to be checked on emptiness.
     * @return True if the given string is null or is empty.
     */
    public static boolean isEmpty(String string) {
        return string == null || string.isEmpty();
    }

    /**
     * Returns <code>true</code> if the given array is null or is empty.
     *
     * @param array The array to be checked on emptiness.
     * @return <code>true</code> if the given array is null or is empty.
     */
    public static boolean isEmpty(Object[] array) {
        return array == null || array.length == 0;
    }

    /**
     * Returns <code>true</code> if the given collection is null or is empty.
     *
     * @param collection The collection to be checked on emptiness.
     * @return <code>true</code> if the given collection is null or is empty.
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * Returns <code>true</code> if the given value is null or is empty. Types of String, Collection, Map, Optional and
     * Array are recognized. If none is recognized, then examine the emptiness of the toString() representation instead.
     *
     * @param value The value to be checked on emptiness.
     * @return <code>true</code> if the given value is null or is empty.
     */
    public static boolean isEmpty(Object value) {
        if (value == null) {
            return true;
        } else if (value instanceof String) {
            return ((String) value).isEmpty();
        } else if (value instanceof Collection<?>) {
            return ((Collection<?>) value).isEmpty();
        } else if (value instanceof Map<?, ?>) {
            return ((Map<?, ?>) value).isEmpty();
        } else if (value instanceof Optional<?>) {
            return !((Optional<?>) value).isPresent();
        } else if (value.getClass().isArray()) {
            return Array.getLength(value) == 0;
        } else {
            return value.toString() == null || value.toString().isEmpty();
        }
    }

    /**
     * Returns true if all values are empty, false if at least one value is not empty.
     *
     * @param values the values to be checked on emptiness
     * @return True if all values are empty, false otherwise
     */
    public static boolean isAllEmpty(Object... values) {
        for (Object value : values) {
            if (!isEmpty(value)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Returns <code>true</code> if at least one value is empty.
     *
     * @param values the values to be checked on emptiness
     * @return <code>true</code> if any value is empty and <code>false</code> if no values are empty
     */
    public static boolean isAnyEmpty(Object... values) {
        for (Object value : values) {
            if (isEmpty(value)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isAllNull(Object... values) {
        for (Object value : values) {
            if (value != null) {
                return false;
            }
        }

        return true;
    }

    public static boolean isAnyNull(Object... values) {
        for (Object value : values) {
            if (value == null) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns <code>true</code> if the given object equals one of the given objects.
     *
     * @param <T> The generic object type.
     * @param object The object to be checked if it equals one of the given objects.
     * @param objects The argument list of objects to be tested for equality.
     * @return <code>true</code> if the given object equals one of the given objects.
     */
    @SafeVarargs
    public static <T> boolean isOneOf(T object, T... objects) {
        for (Object other : objects) {
            if (object == null ? other == null : object.equals(other)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the first non-<code>null</code> object of the argument list, or <code>null</code> if there is no such
     * element.
     *
     * @param <T> The generic object type.
     * @param objects The argument list of objects to be tested for non-<code>null</code>.
     * @return The first non-<code>null</code> object of the argument list, or <code>null</code> if there is no such
     * element.
     */
    @SafeVarargs
    public static <T> T coalesce(T... objects) {
        for (T object : objects) {
            if (object != null) {
                return object;
            }
        }

        return null;
    }

    public static Properties getPropertiesFromFile(String file) throws IOException {
        InputStream is = ClassLoader.getSystemResourceAsStream(file);
        InputStream is2 = null;
        try {
            if (is != null) {
                Properties config = new Properties();
                config.load(is);
                return config;
            } else {
                String remoteclient = "/" + file;
                is2 = Utility.class.getResourceAsStream(remoteclient);
                Properties config = new Properties();
                config.load(is2);
                return config;
            }
        } finally {
            try {
                if (is2 != null)
                    is2.close();
            } catch (Exception e) {
                // nothing can be done about it.
            }
        }
    }

    /**
     * Return the hostname of the local machine.
     */
    public static String getLocalHost() {
        String hostname = null;
        try {
            InetAddress ia = InetAddress.getLocalHost();
            hostname = ia.getHostName();
        } catch (UnknownHostException e) {
            return "localhost";
        }
        return hostname;
    }

    /**
     * Return the hostname of the local machine.
     */
    public static String getLocalAddress() {
        String address = null;
        try {
            InetAddress ia = InetAddress.getLocalHost();
            address = ia.getHostAddress();
        } catch (UnknownHostException e) {
            return "127.0.0.1";
        }
        return address;
    }

    /**
     * This is a convenience method to lookup a remote object by name within the naming context.
     *
     * @exception javax.naming.NamingException if the object with that name could not be found.
     */
    public static Remote lookupObject(String publishedName, Class anInterface) throws javax.naming.NamingException {

        Context ic = new InitialContext();
        Object objRef = ic.lookup(publishedName);
        return (Remote) PortableRemoteObject.narrow(objRef, anInterface);
    }

    /**
     * Returns a character array for the valid characters in a CharBuffer.
     *
     * @param cb
     * @return
     */
    public static char[] toCharArray(final CharBuffer cb) {
        return cb.toString().toCharArray();
    }

    /**
     * Returns a byte array for the valid bytes in a ByteBuffer.
     *
     * @param bb
     * @return
     */
    public static byte[] toByteArray(final ByteBuffer bb) {
        final byte[] result = new byte[bb.limit() - bb.position()];
        bb.get(result);
        return result;
    }

    /**
     * Unmarshal a byte array to an integer. Assume the bytes are in BIGENDIAN order. i.e. array[offset] is the
     * most-significant-byte and array[offset+3] is the least-significant-byte.
     *
     * @param array The array of bytes.
     * @param offset The offset from which to start unmarshalling.
     */
    public static int bytesToInt(byte[] array, int offset) {
        int b1, b2, b3, b4;

        b1 = (array[offset++] << 24) & 0xFF000000;
        b2 = (array[offset++] << 16) & 0x00FF0000;
        b3 = (array[offset++] << 8) & 0x0000FF00;
        b4 = (array[offset++] << 0) & 0x000000FF;

        return (b1 | b2 | b3 | b4);
    }

    /**
     * Marshal an integer to a byte array. The bytes are in BIGENDIAN order. i.e. array[offset] is the most-significant-byte
     * and array[offset+3] is the least-significant-byte.
     *
     * @param array The array of bytes.
     * @param offset The offset from which to start marshalling.
     */
    public static void intToBytes(int value, byte[] array, int offset) {
        array[offset++] = (byte) ((value >>> 24) & 0xFF);
        array[offset++] = (byte) ((value >>> 16) & 0xFF);
        array[offset++] = (byte) ((value >>> 8) & 0xFF);
        array[offset++] = (byte) ((value >>> 0) & 0xFF);
    }

    /**
     * Unmarshal a byte array to an long. Assume the bytes are in BIGENDIAN order. i.e. array[offset] is the
     * most-significant-byte and array[offset+7] is the least-significant-byte.
     *
     * @param array The array of bytes.
     * @param offset The offset from which to start unmarshalling.
     */
    public static long bytesToLong(byte[] array, int offset) {
        long l1, l2;

        l1 = (long) bytesToInt(array, offset) << 32;
        l2 = bytesToInt(array, offset + 4) & 0xFFFFFFFFL;

        return (l1 | l2);
    }

    /**
     * Marshal an long to a byte array. The bytes are in BIGENDIAN order. i.e. array[offset] is the most-significant-byte
     * and array[offset+7] is the least-significant-byte.
     *
     * @param array The array of bytes.
     * @param offset The offset from which to start marshalling.
     */
    public static void longToBytes(long value, byte[] array, int offset) {
        array[offset++] = (byte) ((value >>> 56) & 0xFF);
        array[offset++] = (byte) ((value >>> 48) & 0xFF);
        array[offset++] = (byte) ((value >>> 40) & 0xFF);
        array[offset++] = (byte) ((value >>> 32) & 0xFF);
        array[offset++] = (byte) ((value >>> 24) & 0xFF);
        array[offset++] = (byte) ((value >>> 16) & 0xFF);
        array[offset++] = (byte) ((value >>> 8) & 0xFF);
        array[offset++] = (byte) ((value >>> 0) & 0xFF);
    }

    /**
     * Verify and invoke main if present in the specified class.
     */
    public static void invokeApplicationMain(Class mainClass, String[] args)
            throws InvocationTargetException, IllegalAccessException, ClassNotFoundException {
        String err = localStrings.getLocalString("utility.no.main", "", new Object[] { mainClass });

        // determine the main method using reflection
        // verify that it is public static void and takes
        // String[] as the only argument
        Method mainMethod = null;
        try {
            mainMethod = mainClass.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException msme) {
            _logger.log(Level.SEVERE, CULoggerInfo.exceptionInUtility, msme);
            throw new ClassNotFoundException(err);
        }

        // check modifiers: public static
        // check return type and exceptions
        int modifiers = mainMethod.getModifiers();
        if (!Modifier.isPublic(modifiers) || !Modifier.isStatic(modifiers) || !mainMethod.getReturnType().equals(Void.TYPE)) {
            err = localStrings.getLocalString("utility.main.invalid", "The main method signature is invalid");
            _logger.log(Level.SEVERE, CULoggerInfo.mainNotValid);
            throw new ClassNotFoundException(err);
        }

        // build args to the main and call it
        Object params[] = new Object[1];
        params[0] = args;
        mainMethod.invoke(null, params);

    }

    public static void invokeSetMethod(Object obj, String prop, String value)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class cl = obj.getClass();
        // change first letter to uppercase
        String setMeth = "set" + prop.substring(0, 1).toUpperCase(Locale.US) + prop.substring(1);

        // try string method
        try {
            Class[] cldef = { String.class };
            Method meth = cl.getMethod(setMeth, cldef);
            Object[] params = { value };
            meth.invoke(obj, params);
            return;
        } catch (NoSuchMethodException ex) {
            try {
                // try int method
                Class[] cldef = { Integer.TYPE };
                Method meth = cl.getMethod(setMeth, cldef);
                Object[] params = { Integer.valueOf(value) };
                meth.invoke(obj, params);
                return;
            } catch (NoSuchMethodException nsmex) {
                // try boolean method
                Class[] cldef = { Boolean.TYPE };
                Method meth = cl.getMethod(setMeth, cldef);
                Object[] params = { Boolean.valueOf(value) };
                meth.invoke(obj, params);
                return;
            }
        }
    }

    public static void invokeSetMethodCaseInsensitive(Object obj, String prop, String value)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        String alternateMethodName = null;
        Class cl = obj.getClass();

        String setMeth = "set" + prop;

        Method[] methodsList = cl.getMethods();
        boolean methodFound = false;
        int i = 0;
        for (i = 0; i < methodsList.length; ++i) {
            if (methodsList[i].getName().equalsIgnoreCase(setMeth) == true) {
                Class[] parameterTypes = methodsList[i].getParameterTypes();
                if (parameterTypes.length == 1) {
                    if (parameterTypes[0].getName().equals("java.lang.String")) {
                        methodFound = true;
                        break;
                    } else
                        alternateMethodName = methodsList[i].getName();
                }

            }
        }
        if (methodFound == true) {
            Object[] params = { value };
            methodsList[i].invoke(obj, params);
            return;
        }
        if (alternateMethodName != null) {
            try {
                // try int method
                Class[] cldef = { Integer.TYPE };
                Method meth = cl.getMethod(alternateMethodName, cldef);
                Object[] params = { Integer.valueOf(value) };
                meth.invoke(obj, params);
                return;
            } catch (NoSuchMethodException nsmex) {
                // try boolean method
                Class[] cldef = { Boolean.TYPE };
                Method meth = cl.getMethod(alternateMethodName, cldef);
                Object[] params = { Boolean.valueOf(value) };
                meth.invoke(obj, params);
                return;
            }

        } else
            throw new NoSuchMethodException(setMeth);
    }

    // Ports are marshalled as shorts on the wire. The IDL
    // type is unsigned short, which lacks a convenient representation
    // in Java in the 32768-65536 range. So, we treat ports as
    // ints throught this code, except that marshalling requires a
    // scaling conversion. intToShort and shortToInt are provided
    // for this purpose.

    public static short intToShort(int value) {
        if (value > 32767)
            return (short) (value - 65536);
        return (short) value;
    }

    public static int shortToInt(short value) {
        if (value < 0)
            return value + 65536;
        return value;
    }

    /**
     * Get the current thread's context class loader which is set to the CommonClassLoader by ApplicationServer
     *
     * @return the thread's context classloader if it exists; else the system class loader.
     */
    public static ClassLoader getClassLoader() {
        if (Thread.currentThread().getContextClassLoader() != null) {
            return Thread.currentThread().getContextClassLoader();
        }

        return ClassLoader.getSystemClassLoader();
    }

    /**
     * Loads the class with the common class loader.
     *
     * @param className the class name
     * @return the loaded class
     * @exception if the class is not found.
     */
    public static Class loadClass(String className) throws ClassNotFoundException {
        return getClassLoader().loadClass(className);
    }

    /**
     * Utility routine for setting the context class loader. Returns previous class loader.
     */
    public static ClassLoader setContextClassLoader(ClassLoader newClassLoader) {

        // Can only reference final local variables from dopriveleged block
        final ClassLoader classLoaderToSet = newClassLoader;

        final Thread currentThread = Thread.currentThread();
        ClassLoader originalClassLoader = currentThread.getContextClassLoader();

        if (classLoaderToSet != originalClassLoader) {
            if (System.getSecurityManager() == null) {
                currentThread.setContextClassLoader(classLoaderToSet);
            } else {
                java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
                    @Override
                    public java.lang.Object run() {
                        currentThread.setContextClassLoader(classLoaderToSet);
                        return null;
                    }
                });
            }
        }
        return originalClassLoader;
    }

    public static void setEnvironment() {
        Environment.obtain().activateEnvironment();
    }

    /**
     * Return the value for a given name from the System Properties or the Environmental Variables. The former overrides the
     * latter.
     *
     * @param name - the name of the System Property or Environmental Variable
     * @return the value of the variable or null if it was not found
     */
    public static String getEnvOrProp(String name) {
        // System properties override env. variables
        String envVal = System.getenv(name);
        String sysPropVal = System.getProperty(name);

        if (sysPropVal != null) {
            return sysPropVal;
        }

        return envVal;
    }

    /**
     * Convert the byte array to char array with respect to given charset.
     *
     * @param byteArray
     * @param charset null or "" means default charset
     * @exception CharacterCodingException
     */
    public static char[] convertByteArrayToCharArray(byte[] byteArray, String charset) throws CharacterCodingException {
        if (byteArray == null) {
            return null;
        }

        byte[] bArray = byteArray.clone();
        ByteBuffer byteBuffer = ByteBuffer.wrap(bArray);
        Charset charSet;
        if (charset == null || "".equals(charset)) {
            charSet = Charset.defaultCharset();
        } else if (Charset.isSupported(charset)) {
            charSet = Charset.forName(charset);
        } else {
            CharacterCodingException e = new CharacterCodingException();
            e.initCause(new UnsupportedCharsetException(charset));
            throw e;
        }

        CharsetDecoder decoder = charSet.newDecoder();
        CharBuffer charBuffer = null;
        try {
            charBuffer = decoder.decode(byteBuffer);
        } catch (CharacterCodingException cce) {
            throw cce;
        } catch (Throwable t) {
            CharacterCodingException e = new CharacterCodingException();
            e.initCause(t);
            throw e;
        }
        char[] result = toCharArray(charBuffer);
        clear(byteBuffer);
        clear(charBuffer);

        return result;
    }

    /**
     * Convert the char array to byte array with respect to given charset.
     *
     * @param charArray
     * @param strCharset null or "" means default charset
     * @exception CharacterCodingException
     */
    public static byte[] convertCharArrayToByteArray(char[] charArray, String strCharset) throws CharacterCodingException {
        if (charArray == null) {
            return null;
        }

        char[] cArray = charArray.clone();
        CharBuffer charBuffer = CharBuffer.wrap(cArray);
        Charset charSet;
        if (strCharset == null || "".equals(strCharset)) {
            charSet = Charset.defaultCharset();
        } else if (Charset.isSupported(strCharset)) {
            charSet = Charset.forName(strCharset);
        } else {
            CharacterCodingException e = new CharacterCodingException();
            e.initCause(new UnsupportedCharsetException(strCharset));
            throw e;
        }

        CharsetEncoder encoder = charSet.newEncoder();
        ByteBuffer byteBuffer = null;
        try {
            byteBuffer = encoder.encode(charBuffer);
        } catch (CharacterCodingException cce) {
            throw cce;
        } catch (Throwable t) {
            CharacterCodingException e = new CharacterCodingException();
            e.initCause(t);
            throw e;
        }

        byte[] result = new byte[byteBuffer.remaining()];
        byteBuffer.get(result);
        clear(byteBuffer);
        clear(charBuffer);

        return result.clone();
    }

    private static void clear(ByteBuffer byteBuffer) {
        byte[] bytes = byteBuffer.array();
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = 0;
        }
    }

    private static void clear(CharBuffer charBuffer) {
        char[] chars = charBuffer.array();
        for (int i = 0; i < chars.length; i++) {
            chars[i] = '0';
        }
    }
}
