/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation. 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.helper;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.eclipse.persistence.logging.SessionLog;


/**
 * @author Mitesh Meswani
 * This class is responsible to translate given database name to a DatabasePlatform.
 */
public class DBPlatformHelper {
    private static final String DEFAULTPLATFORM  = "org.eclipse.persistence.platform.database.DatabasePlatform"; // NOI18N

    private final static String PROPERTY_PATH = "org/eclipse/persistence/internal/helper/"; // NOI18N

    private final static String VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME =
        PROPERTY_PATH + "VendorNameToPlatformMapping.properties";  //NOI18N

    /**
     * Holds mapping between possible vendor names to internal platforms defined above.
     * vendor names are treated as regular expressions.
     */
    private static List<String[]> _nameToVendorPlatform = null;

    /** Get Database Platform from vendor name.
     * @param vendorName Input vendor name. Typically this is obtained by querying
     * <code>DatabaseMetaData</code>.
     * @param logger The logger.
     * @return Database platform that corresponds to <code>vendorName</code>.
     * If vendorName does not match any of predefined vendor names, <code>
     * DEFAULTPLATFORM </code> is returned.
     */
    public static String getDBPlatform(String vendorName, String minorVersion, String majorVersion, SessionLog logger) {

        initializeNameToVendorPlatform(logger);

        vendorName = (vendorName == null) ? "Vendor Not Found" : vendorName;
        minorVersion = (minorVersion == null) ? "0" : minorVersion;
        majorVersion = (majorVersion == null) ? "0" : majorVersion;

        String vendor = vendorName + "[" + minorVersion + ", " + majorVersion + "]";

        String detectedDbPlatform = matchVendorNameInProperties(vendor, _nameToVendorPlatform, logger);
        if (logger.shouldLog(SessionLog.FINE) ) {
            logger.log(SessionLog.FINE, SessionLog.CONNECTION, "dbPlatformHelper_detectedVendorPlatform", detectedDbPlatform ); // NOI18N
        }
        if (detectedDbPlatform == null) {
            if(logger.shouldLog(SessionLog.INFO)) {
                logger.log(SessionLog.INFO, SessionLog.CONNECTION, "dbPlatformHelper_defaultingPlatform",  vendor, DEFAULTPLATFORM); // NOI18N
            }
            detectedDbPlatform = DEFAULTPLATFORM;
        }
        return detectedDbPlatform;
    }

    /**
     * Allocate and initialize nameToVendorPlatform if not already done.
     */
    private static List<String[]> initializeNameToVendorPlatform(SessionLog logger) {
        synchronized(DBPlatformHelper.class) {
            if(_nameToVendorPlatform == null) {
                _nameToVendorPlatform = new ArrayList<>();
                try {
                    loadFromResource(_nameToVendorPlatform, VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME,
                                            DBPlatformHelper.class.getClassLoader() );
                } catch (IOException e) {
                    logger.log(SessionLog.WARNING, SessionLog.CONNECTION, "dbPlatformHelper_noMappingFound", VENDOR_NAME_TO_PLATFORM_RESOURCE_NAME);
                }
            }
        }
        return _nameToVendorPlatform;
    }

    /**
     * Match vendorName in properties specified by _nameToVendorPlatform.
     */
    private static String matchVendorNameInProperties(String vendorName,
            List<String[]> nameToVendorPlatform, SessionLog logger) {
        String dbPlatform = null;
        //Iterate over all properties till we find match.
        for( Iterator<String[]> iterator = nameToVendorPlatform.iterator();
                dbPlatform == null && iterator.hasNext();) {
            String[] entry = iterator.next();
            String regExpr = entry[0];
            String value = entry[1];
            if (logger.shouldLog(SessionLog.FINEST)) {
                logger.log(SessionLog.FINEST, SessionLog.CONNECTION, "dbPlatformHelper_regExprDbPlatform", regExpr,
                    value); // NOI18N
            }
            if( matchPattern(regExpr, vendorName, logger) ) {
                dbPlatform = value;
            }
        }
        return dbPlatform;
    }

   /** Matches target to pattern specified regExp. Returns false if there is
    * any error compiling regExp.
    * @param regExp The regular expression.
    * @param target The target against which we are trying to match regExp.
    * @return false if there is error compiling regExp or target does not
    * match regExp. true if regExp matches pattern.
    */
    private static boolean matchPattern(String regExp, String target, SessionLog logger) {
        boolean matches = false;
        try {
            matches = Pattern.matches(regExp,target);
        } catch (PatternSyntaxException e){
            if(logger.shouldLog(SessionLog.FINE)) {
                logger.log(SessionLog.FINE, SessionLog.CONNECTION, "dbPlatformHelper_patternSyntaxException", e); // NOI18N
            }
        }
        return matches;
    }

    //-----Property Loading helper methods ----/
    private static void loadFromResource(List<String[]> properties, String resourceName, ClassLoader classLoader)
            throws IOException {
        load(properties, resourceName, classLoader);
    }

    /**
     * Loads properties list from the specified resource
     * into specified Properties object.
     * @param properties    Properties object to load
     * @param resourceName    Name of resource.
     *                      If loadFromFile  is true, this is fully qualified path name to a file.
     *                      param classLoader is ignored.
     *                      If loadFromFile  is false,this is resource name.
     * @param classLoader   The class loader that should be used to load the resource. If null,primordial
     *                      class loader is used.
     */
    private static void load(List<String[]> properties, final String resourceName,
            final ClassLoader classLoader)
                            throws IOException {
        try (BufferedReader bin = new BufferedReader(
                new InputStreamReader(openResourceInputStream(resourceName,classLoader)))) {
            for (String line = bin.readLine(); line != null; line = bin.readLine()) {
                String[] keyValue = validateLineForReturnAsKeyValueArray(line);
                if (keyValue != null) {
                    properties.add(keyValue);
                }
            }
        }
    }

    /**
     * Open resourceName as input stream inside doPriviledged block
     */
    private static InputStream openResourceInputStream(final String resourceName, final ClassLoader classLoader) {
        return (InputStream) AccessController.doPrivileged(
            new PrivilegedAction() {
                @Override
                public Object run() {
                    if (classLoader != null) {
                        return classLoader.getResourceAsStream(resourceName);
                    } else {
                        return ClassLoader.getSystemResourceAsStream(resourceName);
                    }
                }
            }
        );
    }

    private static String[] validateLineForReturnAsKeyValueArray(String line) {
        if (line == null || line.length() == 0) {
            return null;
        }
        // trim leading AND trailing space
        line = line.trim();

        // check for comment and empty line
        if (line.length() == 0 || line.startsWith("#")) {
            return null;
        }

        // check line contains valid properties '=' separator
        int indexOfEquals = line.indexOf('=');
        if (indexOfEquals == -1) {
            return null;
        }
        String key = line.substring(0, indexOfEquals);
        String value = line.substring(indexOfEquals + 1, line.length());
        return new String[] { key, value };
    }

}
