/**
 *                                                                            
 * 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 javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;

import org.eclipse.osbp.preferences.ProductConfigurationPrefs.DDL_GENERATION;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.sessions.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PersistenceUnitConfiguration extends AItemDescribed {

	private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceUnitConfiguration.class);
	private static final PersistenceUnitConfiguration WORKER = new PersistenceUnitConfiguration();

	public static final class PersistenceUnitItemDescription extends ItemDescription {

		public static final PersistenceUnitItemDescription INSTANCE = new PersistenceUnitItemDescription();

		private static final String ROW_NAME = "Persistence Unit";
		public static final String JNDI_NAME = "JNDI Data Source";
		public static final String DDL_GENERATION = "DDL Generation";
		public static final String BATCH_WRITING = "Batch Writing";
		public static final String DEPLOY_ON_STARTUP = "Deploy on Startup";
		public static final String QUERY_CACHE = "Query Cache";
		public static final String BATCH_WRITING_SIZE = "Batch Writing Size";
		public static final String CACHE_STATEMENTS = "Cache Statements";
		public static final String CACHE_STATEMENTS_SIZE = "Cache Statements Size";
		public static final String LOGGING_LEVEL = "Logging Level";
		public static final String PERSISTENCE_XML_PATH = "Persistence XML Path";

		protected PersistenceUnitItemDescription() {
			super(ROW_NAME, JNDI_NAME, Type.Integer, DDL_GENERATION, Type.String, BATCH_WRITING, Type.String,
					DEPLOY_ON_STARTUP, Type.Boolean, QUERY_CACHE, Type.Boolean, BATCH_WRITING_SIZE, Type.Integer, CACHE_STATEMENTS,
					Type.Boolean, CACHE_STATEMENTS_SIZE, Type.Integer, LOGGING_LEVEL, Type.String, PERSISTENCE_XML_PATH, Type.String);
		}
	}

	private String name;
	private String jndiName;
	private Boolean deployOnStartup;
	private Boolean queryCache;
	private String batchWriting;
	private Integer batchWritingSize;
	private Boolean cacheStatements;
	private Integer cacheStatementsSize;
	private String loggingLevel;
	private String ddlGeneration;
	private String persistenceXMLPath;

	public static final boolean DEPLOY_ON_STARTUP = true;
	public static final boolean QUERY_CACHE = true;
	public static final int BATCH_WRITING_SIZE = 1000;
	public static final boolean CACHE_STATEMENTS = true;
	public static final int CACHE_STATEMENTS_SIZE = 200;
	public static final String LOGGING_LEVEL = "off";
	public static final String PERSISTENCE_XML_PATH = PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML_DEFAULT;

	public PersistenceUnitConfiguration(String name, String jndiName, String batchWriting, String ddlGeneration) {
		this(name, jndiName, DEPLOY_ON_STARTUP, QUERY_CACHE, batchWriting, BATCH_WRITING_SIZE, CACHE_STATEMENTS,
				CACHE_STATEMENTS_SIZE, LOGGING_LEVEL, ddlGeneration, PERSISTENCE_XML_PATH);
	} // NOSONAR

	public PersistenceUnitConfiguration(String name, String jndiName,
			boolean deployOnStartup, boolean queryCache, String batchWriting, int batchWritingSize, boolean cacheStatements,
			int cacheStatementsSize, String loggingLevel, String ddlGeneration, String persistenceXMLPath) {
		super(PersistenceUnitItemDescription.INSTANCE);
		this.name = name;
		this.jndiName = (jndiName == null || jndiName.isEmpty()) ? name : jndiName;
		this.deployOnStartup = deployOnStartup;
		this.queryCache = queryCache;
		this.batchWriting = batchWriting;
		this.batchWritingSize = batchWritingSize;
		this.cacheStatements = cacheStatements;
		this.cacheStatementsSize = cacheStatementsSize;
		this.loggingLevel = (loggingLevel == null || loggingLevel.isEmpty()) ? LOGGING_LEVEL : loggingLevel;
		this.ddlGeneration = (ddlGeneration == null || ddlGeneration.isEmpty()) ? DDL_GENERATION.UPDATE.eclipseLink() : ddlGeneration;
		this.persistenceXMLPath = (persistenceXMLPath == null || persistenceXMLPath.isEmpty()) ? PERSISTENCE_XML_PATH : persistenceXMLPath;
	}

	private PersistenceUnitConfiguration() {
		super(PersistenceUnitItemDescription.INSTANCE);
		this.name = "noname";
		this.jndiName = "njndioname";
		this.deployOnStartup = false;
		this.queryCache = false;
		this.batchWriting = "nobatchWriting";
		this.batchWritingSize = 0;
		this.cacheStatements = false;
		this.cacheStatementsSize = 0;
		this.loggingLevel = null;
		this.ddlGeneration = null;
		this.persistenceXMLPath = null;
	}

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

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

	@Override
	public String getValue(String attribute) { // NOSONAR
		switch (attribute) { // NOSONAR
		case PersistenceUnitItemDescription.JNDI_NAME:
			return jndiName;
		case PersistenceUnitItemDescription.DDL_GENERATION:
			return ddlGeneration;
		case PersistenceUnitItemDescription.BATCH_WRITING:
			return batchWriting;
		case PersistenceUnitItemDescription.DEPLOY_ON_STARTUP:
			return Boolean.toString(deployOnStartup);
		case PersistenceUnitItemDescription.QUERY_CACHE:
			return Boolean.toString(queryCache);
		case PersistenceUnitItemDescription.BATCH_WRITING_SIZE:
			return Integer.toString(batchWritingSize);
		case PersistenceUnitItemDescription.CACHE_STATEMENTS:
			return Boolean.toString(cacheStatements);
		case PersistenceUnitItemDescription.CACHE_STATEMENTS_SIZE:
			return Integer.toString(cacheStatementsSize);
		case PersistenceUnitItemDescription.LOGGING_LEVEL:
			return loggingLevel;
		case PersistenceUnitItemDescription.PERSISTENCE_XML_PATH:
			return persistenceXMLPath;
		}
		return null;
	}

	@Override
	public void setValue(String attribute, String value) { // NOSONAR
		switch (attribute) { // NOSONAR
		case PersistenceUnitItemDescription.JNDI_NAME:
			jndiName = value;
			return; // NOSONAR
		case PersistenceUnitItemDescription.DDL_GENERATION:
			ddlGeneration = value;
			return; // NOSONAR
		case PersistenceUnitItemDescription.BATCH_WRITING:
			batchWriting = value;
			return; // NOSONAR
		case PersistenceUnitItemDescription.DEPLOY_ON_STARTUP:
			deployOnStartup = ItemDescription.parseBoolean(value, deployOnStartup);
			return; // NOSONAR
		case PersistenceUnitItemDescription.QUERY_CACHE:
			queryCache = ItemDescription.parseBoolean(value, queryCache);
			return; // NOSONAR
		case PersistenceUnitItemDescription.BATCH_WRITING_SIZE:
			batchWritingSize = ItemDescription.parseInt(value, batchWritingSize);
			return; // NOSONAR
		case PersistenceUnitItemDescription.CACHE_STATEMENTS:
			cacheStatements = ItemDescription.parseBoolean(value, cacheStatements);
			return; // NOSONAR
		case PersistenceUnitItemDescription.CACHE_STATEMENTS_SIZE:
			cacheStatementsSize = ItemDescription.parseInt(value, cacheStatementsSize);
			return; // NOSONAR
		case PersistenceUnitItemDescription.LOGGING_LEVEL:
			loggingLevel = value;
			return; // NOSONAR
		case PersistenceUnitItemDescription.PERSISTENCE_XML_PATH:
			persistenceXMLPath = value;
			return; // NOSONAR
		}
	}

	public String getJndiName() {
		return jndiName;
	}

	public Boolean getDeployOnStartup() {
		return deployOnStartup;
	}

	public Boolean getQueryCache() {
		return queryCache;
	}

	public String getBatchWriting() {
		return batchWriting;
	}

	public Integer getBatchWritingSize() {
		return batchWritingSize;
	}

	public Boolean getCacheStatements() {
		return cacheStatements;
	}

	public Integer getCacheStatementsSize() {
		return cacheStatementsSize;
	}

	public String getLoggingLevel() {
		return loggingLevel;
	}

	public String getDdlGeneration() {
		return ddlGeneration;
	}

	public String getPersistenceXMLPath() {
		return persistenceXMLPath;
	}

	protected Properties getPersistenceUnitProperties(CommonDataSource dataSource, ClassLoader classLoader) {
		Properties properties = new Properties();
		if (dataSource instanceof XADataSource) {
			properties.put(PersistenceUnitProperties.JTA_DATASOURCE, (XADataSource) dataSource);
		} else if (dataSource instanceof DataSource) {
			properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, (DataSource) dataSource);
		} else {
			LOGGER.error("no suitable datasource found");
		}
		// optimizations
		properties.put(PersistenceUnitProperties.DEPLOY_ON_STARTUP, deployOnStartup.toString());
		properties.put(PersistenceUnitProperties.QUERY_CACHE, queryCache.toString());
		// values are: JDBC, Buffered, Oracle-JDBC, <custom-class>, None
		properties.put(PersistenceUnitProperties.BATCH_WRITING, batchWriting);
		properties.put(PersistenceUnitProperties.BATCH_WRITING_SIZE, batchWritingSize.toString());
		properties.put(PersistenceUnitProperties.CACHE_STATEMENTS, cacheStatements.toString());
		properties.put(PersistenceUnitProperties.CACHE_STATEMENTS_SIZE, cacheStatementsSize.toString());
		// values are: OFF, DEBUG, INFO, ERROR
		properties.put(PersistenceUnitProperties.LOGGING_LEVEL, loggingLevel);
		// values are: create-tables, drop-tables, drop-and-create-tables,
		// drop-and-create-tables, create-or-extend-tables, none
		properties.put(PersistenceUnitProperties.DDL_GENERATION, ddlGeneration);
		properties.put(PersistenceUnitProperties.CLASSLOADER, classLoader);
		properties.put(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, persistenceXMLPath);
		properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, CustomCustomizer.class.getName());
		return properties;
	}

	@Override
	protected String _serialize() {
		return name + VALUE_SEPARATOR + jndiName + VALUE_SEPARATOR + deployOnStartup + VALUE_SEPARATOR
				+ queryCache + VALUE_SEPARATOR + batchWriting + VALUE_SEPARATOR + batchWritingSize + VALUE_SEPARATOR + cacheStatements
				+ VALUE_SEPARATOR + cacheStatementsSize + VALUE_SEPARATOR + loggingLevel + VALUE_SEPARATOR + ddlGeneration
				+ VALUE_SEPARATOR + persistenceXMLPath;
	}

	@Override
	protected AItemDescribed _deserialize(String serialized) {
		String[] tokens = serialized.split(VALUE_SEPARATOR);
		return new PersistenceUnitConfiguration(tokens[0], tokens[1], ItemDescription.parseBoolean(tokens[2], true),
				ItemDescription.parseBoolean(tokens[3], true), tokens[4], ItemDescription.parseInt(tokens[5], 0),
				ItemDescription.parseBoolean(tokens[6], true), ItemDescription.parseInt(tokens[7], 0), tokens[8], tokens[9], tokens[10]);
	}

	public static String serialize(Collection<PersistenceUnitConfiguration> persistenceUnits) {
		String retcode = null;
		if (persistenceUnits == null) {
			retcode = "";
		} else {
			for (PersistenceUnitConfiguration persistenceUnit : persistenceUnits) {
				if (retcode == null) {
					retcode = persistenceUnit._serialize();
				} else {
					retcode += ITEM_SEPARATOR + persistenceUnit._serialize();
				}
			}
		}
		return retcode;
	}

	public static Map<String, PersistenceUnitConfiguration> deserialize(String value) {
		Map<String, PersistenceUnitConfiguration> persistenceUnits = new TreeMap<>();
		String[] persistenceUnitItems = value.split(ITEM_SEPARATOR);
		for (String persistenceUnitItem : persistenceUnitItems) {
			PersistenceUnitConfiguration persistenceUnit = (PersistenceUnitConfiguration) WORKER._deserialize(persistenceUnitItem);
			persistenceUnits.put(persistenceUnit.getName(), persistenceUnit);
		}
		return persistenceUnits;
	}

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

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

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

	public static class CustomCustomizer implements SessionCustomizer {

		@Override
		public void customize(Session session) throws Exception {
		}
	}

}
