/*
 * 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;
	
	static ConnectionPropertiesPatcher getPatcher(String _dbType, ConnectionProperties connectionProperties) {
		DbType dbType = DbType.valueOf(_dbType);
		ConnectionPropertiesPatcher patcher = null;
		switch (dbType) {
			case db2:
				patcher = new Db2Patcher();
				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));
	}
	
	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);
}
