/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.preferences;

import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import org.osgi.service.jdbc.DataSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/**
 * Helper class containing DataSource configuration data needed for JPA and JDBC
 */
public class DataSourceConfiguration extends AItemDescribed {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceConfiguration.class);
	
	public static final class DataSourceItemDescription extends ItemDescription {
		
		public static final DataSourceItemDescription INSTANCE = new DataSourceItemDescription();
		
		private static final  String ROW_NAME = "JNDI Data Source";
		public static final String DATABASE_TYPE = "Database Type";
		public static final String DRIVER_CLASS = "Driver Class";
		public static final String SERVER_NAME = "Server Name";
		public static final String SERVER_PORT = "Server Port";
		public static final String DATABASE_NAME = "Database Name";
		public static final String DATABASE_USER = "Database User";
		public static final String DATABASE_PASSWORD = "Database Password"; // NOSONAR

		protected DataSourceItemDescription() {
			super(ROW_NAME,
					DATABASE_TYPE, Type.DatabaseType,
					DRIVER_CLASS, Type.String,
					SERVER_NAME, Type.String,
					SERVER_PORT, Type.Integer,
					DATABASE_NAME, Type.String,
					DATABASE_USER, Type.String,
					DATABASE_PASSWORD, Type.String
			);
		}
	}
	
	private String fName;
	private EnumDatabaseVendor fDataBaseVendor;
	private String fDriverVendor;
	private String fDriverType;
	private String fDriverClass;
	private String fServerName;
	private int fServerPort;
	private String fDatabaseName;
	private String fDatabaseUser;
	private String fDatabasePass;
	private String fJdbcUrlFormat;

	private static final DataSourceConfiguration WORKER = new DataSourceConfiguration();
	
	private DataSourceConfiguration() {
		super(DataSourceItemDescription.INSTANCE);
		fName = null;
		fDataBaseVendor = null;
		fDriverVendor = null;
		fDriverType = null;
		fDriverClass = null;
		fServerName = null;
		fServerPort = 0;
		fDatabaseName = null;
		fDatabaseUser = null;
		fDatabasePass = null;
		fJdbcUrlFormat = null;
	}
	
	public DataSourceConfiguration(
		String name,
		EnumDatabaseVendor dataBaseVendor,
		String serverName, int serverPort,
		String databaseName, String databaseUser, String databasePass) {
		this(
			name,
			dataBaseVendor,
			dataBaseVendor.getDriverVendor(),
			dataBaseVendor.getDriverType(),
			dataBaseVendor.getDriverClass(),
			serverName, serverPort,
			databaseName, databaseUser, databasePass,
			null
		);
	}

	protected DataSourceConfiguration( // NOSONAR
		String name,
		EnumDatabaseVendor dataBaseVendor,
		String driverVendor, String driverType, String driverClass,
		String serverName, int serverPort,
		String databaseName, String databaseUser, String databasePass,
		String jdbcUrlFormat) {
		super(DataSourceItemDescription.INSTANCE);
		fName = name;
		fDataBaseVendor = dataBaseVendor;
		fDriverVendor = (driverVendor == null || driverVendor.isEmpty()) ? dataBaseVendor.getDriverVendor() : driverVendor;
		fDriverType = (driverType == null || driverType.isEmpty()) ? dataBaseVendor.getDriverType() : driverType;
		fDriverClass = (driverClass == null || driverClass.isEmpty()) ? dataBaseVendor.getDriverClass() : driverClass;
		fServerName = (serverName == null ? "" : serverName);
		fServerPort = (serverPort < 0 ? 0 : serverPort);
		fDatabaseName = databaseName;
		fDatabaseUser = databaseUser;
		fDatabasePass = databasePass;
		fJdbcUrlFormat = jdbcUrlFormat;
	}

	@Override
	public String getName() {
		return fName;
	}

	@Override
	public void setName(String name) {
		fName = name;
	}

	@Override
	public String getValue(String attribute) { // NOSONAR
		switch (attribute) { // NOSONAR
			case DataSourceItemDescription.DATABASE_TYPE: return fDataBaseVendor.toString();
			case DataSourceItemDescription.DRIVER_CLASS: return fDriverClass;
			case DataSourceItemDescription.SERVER_NAME: return fServerName;
			case DataSourceItemDescription.SERVER_PORT: return ((Integer)fServerPort).toString();
			case DataSourceItemDescription.DATABASE_NAME: return fDatabaseName;
			case DataSourceItemDescription.DATABASE_USER: return fDatabaseUser;
			case DataSourceItemDescription.DATABASE_PASSWORD: return fDatabasePass;
		}
		return null;
	}

	@Override
	public void setValue(String attribute, String value) {
		switch (attribute) { // NOSONAR
			case DataSourceItemDescription.DATABASE_TYPE: { // NOSONAR
				fDataBaseVendor = EnumDatabaseVendor.byName(value, value, value);
				fDriverVendor = fDataBaseVendor.getDriverVendor();
				fDriverType = fDataBaseVendor.getDriverType();
				fDriverClass = fDataBaseVendor.getDriverClass();
				break;
			}
			case DataSourceItemDescription.DRIVER_CLASS: {  // NOSONAR
				fDriverClass = value; 
				break;
			}
			case DataSourceItemDescription.SERVER_NAME: {  // NOSONAR
				fServerName = value; 
				break;
			}
			case DataSourceItemDescription.SERVER_PORT: { // NOSONAR
				fServerPort = ItemDescription.parseInt(value, fServerPort); 
				break;
			}
			case DataSourceItemDescription.DATABASE_NAME: { // NOSONAR
				fDatabaseName = value; 
				break;
			}
			case DataSourceItemDescription.DATABASE_USER: { // NOSONAR
				fDatabaseUser = value; 
				break;
			}
			case DataSourceItemDescription.DATABASE_PASSWORD: { // NOSONAR
				fDatabasePass = value; 
				break;
			}
		}
	}

	/**
	 * @return	the name of the jdbc driver class
	 */
	public String getDriverClass() {
		return fDriverClass;
	}

	public String getDriverVendor() {
		return fDriverVendor;
	}

	public String getDriverType() {
		return fDriverType;
	}

	public String getServerName() {
		return fServerName;
	}

	public int getServerPort() {
		return fServerPort;
	}

	public String getDatabaseName() {
		return fDatabaseName;
	}

	public String getDatabaseUser() {
		return fDatabaseUser;
	}

	public String getDatabasePass() {
		return fDatabasePass; // NOSONAR
	}

	public EnumDatabaseVendor getDatabaseVendor() {
		return fDataBaseVendor;
	}

	public String getDefaultBatchWriting() {
		if  (fDataBaseVendor != null) {
			return fDataBaseVendor.getPersistenceBatchWriting();
		}
		return null;
	}

	public String getDefaultSchemaName() {
		switch (fDataBaseVendor) { // NOSONAR
			case H2_IN_MEMORY:
				return "h2memory";
			case H2_LOCAL_FILE:
				return "h2localfile";
			case MYSQL:
				return getDatabaseName();
			case ORACLE:
				return getDatabaseUser();
			case DERBY_IN_MEMORY:
				return "APP";
			case DERBY_LOCAL_FILE:
				return "APP";
			case DERBY_CLIENT:
				return getDatabaseUser();
		}
		return null;
	}
	
	/**
	 * @return	the properties needed to define a DataSource
	 */
	protected Properties getDataSourceProperties() {
		Properties properties = new Properties();
		if (fDriverType != null && fDriverType.length() > 0) {
			setDataSourceProperty(properties, "driverType", fDriverType);
		}
		setDataSourceProperty(properties, DataSourceFactory.JDBC_SERVER_NAME, fServerName);
		setDataSourceProperty(properties, DataSourceFactory.JDBC_PORT_NUMBER, ((Integer)fServerPort).toString());
		setDataSourceProperty(properties, DataSourceFactory.JDBC_DATABASE_NAME, fDatabaseName);
		setDataSourceProperty(properties, DataSourceFactory.JDBC_USER, fDatabaseUser);
		setDataSourceProperty(properties, DataSourceFactory.JDBC_PASSWORD, fDatabasePass);
		setDataSourceProperty(properties, DataSourceFactory.JDBC_URL, fDataBaseVendor.jdbcUrl(fDriverVendor, fDriverType, fServerName, fServerPort, fDatabaseName, fJdbcUrlFormat));
		return properties;
	}

	private void setDataSourceProperty(Properties properties, String key, String value) {
		if	(fDataBaseVendor.supportsPropertyKey(key)) {
			properties.put(key, value);
		}
		else {
			LOGGER.debug("ignoring unsupported property key '"+key+"' for driver vendor "+fDataBaseVendor.name());
		}
	}
	
	/**
	 * @return	the properties needed to define a JPA connection
	 */
	protected Properties getJpaProperties() {
		Properties properties = new Properties();
	    properties.put("javax.persistence.jdbc.driver"	, getDriverClass());
	    properties.put("javax.persistence.jdbc.url"		, fDataBaseVendor.jdbcUrl(fDriverVendor, fDriverType, fServerName, fServerPort, fDatabaseName, fJdbcUrlFormat));
	    properties.put("javax.persistence.jdbc.user"	, fDatabaseUser);
	    properties.put("javax.persistence.jdbc.password", fDatabasePass);
	    return properties;
	}
	
	@Override
	protected String _serialize() {
		return fName
			+VALUE_SEPARATOR+fDataBaseVendor.toString()
			+VALUE_SEPARATOR+fDriverVendor
			+VALUE_SEPARATOR+fDriverType
			+VALUE_SEPARATOR+fDriverClass
			+VALUE_SEPARATOR+fServerName
			+VALUE_SEPARATOR+fServerPort
			+VALUE_SEPARATOR+fDatabaseName
			+VALUE_SEPARATOR+fDatabaseUser
			+VALUE_SEPARATOR+fDatabasePass
			+VALUE_SEPARATOR+(fJdbcUrlFormat == null ? "" : fJdbcUrlFormat)
			;
	}

	@Override
	protected AItemDescribed _deserialize(String serialized) {
		String[] tokens = serialized.split(VALUE_SEPARATOR);
		String vendorName = tokens[1];
		String driverVendor = tokens[2];
		String dataBaseName = (tokens.length < 8) ? "" : tokens[7];
		return new DataSourceConfiguration( // NOSONAR
			tokens[0],
			EnumDatabaseVendor.byName(vendorName, driverVendor, dataBaseName),
			tokens[2],
			tokens[3],
			tokens[4],
			tokens[5],
			ItemDescription.parseInt(tokens[6], 0),
			dataBaseName,
			(tokens.length < 9) ? "" : tokens[8],
			(tokens.length < 10) ? "" : tokens[9],
			(tokens.length < 11) || tokens[10].isEmpty() ? null : tokens[10]
		);
	}

	public static String serialize(Collection<DataSourceConfiguration> dataSources) {
		String retcode = null;
		for	(DataSourceConfiguration datasource : dataSources) {
			if	(retcode == null) {
				retcode = datasource._serialize();
			}
			else {
				retcode += ITEM_SEPARATOR+datasource._serialize();
			}
		}
		return retcode;
	}

	public static Map<String, DataSourceConfiguration> deserialize(String value) {
		Map<String, DataSourceConfiguration> dataSources = new TreeMap<>();
		String[] datasourceItems = value.split(ITEM_SEPARATOR);
		for(String datasourceItem : datasourceItems) {
			DataSourceConfiguration dataSource = (DataSourceConfiguration) WORKER._deserialize(datasourceItem);
			dataSources.put(dataSource.getName(), dataSource);
		}
		return dataSources;
	}

	@Override
	public SubItem[] getSubItems() {
		return null;
	}

	@Override
	public String getIconName() {
		return null;
	}

	@Override
	public String getRowName() {
		return null;
	}
}
