/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.cli;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.openmeetings.cli.ConnectionProperties.DbType;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public abstract class ConnectionPropertiesPatcher {
	protected static final String URL_PREFIX = "Url=";
	protected ConnectionProperties connectionProperties;
	
	public static ConnectionPropertiesPatcher getPatcher(String _dbType, ConnectionProperties connectionProperties) {
		DbType dbType = DbType.valueOf(_dbType);
		ConnectionPropertiesPatcher patcher = null;
		switch (dbType) {
			case db2:
				patcher = new Db2Patcher();
				break;
			case mssql:
				patcher = new MssqlPatcher();
				break;
			case mysql:
				patcher = new MysqlPatcher();
				break;
			case oracle:
				patcher = new OraclePatcher();
				break;
			case postgresql:
				patcher = new PostgresPatcher();
				break;
			case derby:
			default:
				patcher = new DerbyPatcher();
				break;
		}
		patcher.connectionProperties = connectionProperties;
		return patcher;
	}
	
	static ConnectionProperties getConnectionProperties(File conf) throws Exception {
		ConnectionProperties connectionProperties = new ConnectionProperties();
		Document doc = getDocument(conf);
		Attr attr = getConnectionProperties(doc);
		String[] tokens = attr.getValue().split(",");
		processBasicProperties(tokens, null, null, connectionProperties);
		
		return connectionProperties;
	}
	
	private static Document getDocument(File xml) throws Exception {
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		//dbFactory.setNamespaceAware(true);
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		return dBuilder.parse(xml);
	}
	
	private static Attr getConnectionProperties(Document doc) throws Exception {
		XPath xPath = XPathFactory.newInstance().newXPath();
		XPathExpression expr = xPath.compile("/persistence/persistence-unit/properties/property[@name='openjpa.ConnectionProperties']");

		Element element = (Element)expr.evaluate(doc, XPathConstants.NODE);
		return element.getAttributeNode("value");
	}
	
	public void patch(File srcXml, File destXml, String host, String port, String db, String user, String pass) throws Exception {
		Document doc = getDocument(srcXml);
		
		Attr val = getConnectionProperties(doc);
		val = patchAttribute(val, host, port, db, user, pass);
		
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(doc);
		transformer.transform(source, new StreamResult(destXml.getCanonicalPath())); //this constructor is used to avoid transforming path to URI
	}
	
	protected Attr patchAttribute(Attr attr, String host, String port, String db, String user, String pass) {
		String[] tokens = attr.getValue().split(",");
		processBasicProperties(tokens, user, pass, connectionProperties);
		patchDb(tokens, host, port, db);
		attr.setValue(StringUtils.join(tokens, ","));
		return attr;
	}

	protected static void patchProp(String[] tokens, int idx, String name, String value) {
		String prop = tokens[idx].trim();
		if (prop.startsWith(name)) {
			prop = name + "=" + StringEscapeUtils.escapeXml(value);
			tokens[idx] = prop;
		}
	}
	
	private static void processBasicProperties(String[] tokens, String user,
			String pass, ConnectionProperties connectionProperties) {
		String prop;
		for (int i = 0; i < tokens.length; ++i) {
			prop = getPropFromPersistence(tokens, i, "DriverClassName");
			if (prop != null) {
				connectionProperties.setDriver(prop);
			}
			
			if (user != null) {
				patchProp(tokens, i, "Username", user);
				connectionProperties.setLogin(user);
			} else {
				prop = getPropFromPersistence(tokens, i, "Username");
				if (prop != null) {
					connectionProperties.setLogin(prop);
				}
			}
			
			if (pass != null) {
				patchProp(tokens, i, "Password", pass);
				connectionProperties.setPassword(pass);
			} else {
				prop = getPropFromPersistence(tokens, i, "Password");
				if (prop != null) {
					connectionProperties.setPassword(prop);
				}
			}
			prop = getPropFromPersistence(tokens, i, "Url");
			if (prop != null) {
				try {
					//will try to "guess" dbType
					String[] parts = prop.split(":");
					connectionProperties.setDbType(DbType.valueOf(parts[1]));
				} catch (Exception e) {
					//ignore
				}
				connectionProperties.setURL(prop);
			}
		}
	}
	
	protected static String getPropFromPersistence(String[] tokens, int idx, String name){
		String prop = tokens[idx].trim();
		if (prop.startsWith(name)) {
			//From "Username=root" getting only "root"
			return prop.substring(prop.indexOf("=") + 1);
		}
		return null;
	}
	
	private void patchDb(String[] tokens, String host, String _port, String _db) {
		for (int i = 0; i < tokens.length; ++i) {
			String prop = tokens[i].trim();
			if (prop.startsWith(URL_PREFIX)) {
				String url = getUrl(prop.substring(URL_PREFIX.length()), host, _port, _db);
				connectionProperties.setURL(url);
				tokens[i] = URL_PREFIX + url;
				break;
			}
		}
	}
	
	protected abstract String getUrl(String url, String host, String port, String db);
}
