/**************************************************************
 *
 * 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 testlib.uno;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyState;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.ElementExistException;
import com.sun.star.container.XNameAccess;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.sdb.XDocumentDataSource;
import com.sun.star.sdb.XOfficeDatabaseDocument;
import com.sun.star.sdbc.SQLException;
import com.sun.star.sdbc.XCloseable;
import com.sun.star.sdbc.XConnection;
import com.sun.star.sdbc.XDataSource;
import com.sun.star.sdbc.XStatement;
import com.sun.star.sdbcx.XAppend;
import com.sun.star.sdbcx.XTablesSupplier;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.util.CloseVetoException;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.io.File;

import org.openoffice.test.common.FileUtil;


public class DBUtil {
	// the service factory
	protected static XMultiServiceFactory m_orb;
	// the URL of the temporary file used for the database document
	protected static String m_databaseDocumentFile;
	// the database document
	protected static XOfficeDatabaseDocument m_databaseDocument;
	// the data source belonging to the database document
	protected static XDataSource m_dataSource;
	// the default connection
	protected static XConnection m_connection;


	static public void createNewDocument(final XMultiServiceFactory orb)
			throws Exception {
		m_orb = orb;
		createDBDocument();
	}

	static public void loadNewDocument(final XMultiServiceFactory orb,
			final String _existingDocumentURL) throws Exception {
		m_orb = orb;
		getDocument(_existingDocumentURL);
	}

	/**
	 * creates an empty database document in a temporary location
	 */
	public static void createDBDocument() throws Exception {
		final File documentFile = File.createTempFile("testdb", ".odb");
		if (documentFile.exists())
			documentFile.delete();
		m_databaseDocumentFile = FileUtil.getUrl(documentFile);
		m_databaseDocument = (XOfficeDatabaseDocument) UnoRuntime
				.queryInterface(
						XOfficeDatabaseDocument.class,
						m_orb.createInstance("com.sun.star.sdb.OfficeDatabaseDocument"));
		m_dataSource = m_databaseDocument.getDataSource();

		final XPropertySet dsProperties = (XPropertySet) UnoRuntime
				.queryInterface(XPropertySet.class,
						m_databaseDocument.getDataSource());
		dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb");

		final XStorable storable = (XStorable) UnoRuntime.queryInterface(
				XStorable.class, m_databaseDocument);
		storable.storeAsURL(m_databaseDocumentFile,
				new PropertyValue[] { new PropertyValue("PickListEntry", 0,
						false, PropertyState.DIRECT_VALUE) });
	}


	public static void getDocument(final String _docURL) throws Exception {
		m_databaseDocumentFile = _docURL;

		final XNameAccess dbContext = (XNameAccess) UnoRuntime.queryInterface(
				XNameAccess.class,
				m_orb.createInstance("com.sun.star.sdb.DatabaseContext"));
		final XDocumentDataSource dataSource = (XDocumentDataSource) UnoRuntime.queryInterface(
				XDocumentDataSource.class, dbContext.getByName(_docURL));

		m_databaseDocument = dataSource.getDatabaseDocument();
		m_dataSource = m_databaseDocument.getDataSource();
	}

	/**
	 * drops the table with a given name
	 *
	 * @param _name
	 *            the name of the table to drop
	 * @param _ifExists
	 *            TRUE if it should be dropped only when it exists.
	 */
	static public void dropTable(final String _name, final boolean _ifExists)
			throws SQLException {
		final StringBuffer dropStatement = new StringBuffer("DROP TABLE \"");
		dropStatement.append(_name);
		if (_ifExists) {
			dropStatement.append("\" IF EXISTS");
		}
		executeSQL(dropStatement.toString());
	}

	static public void createTable(String _name,
			HsqlColumnDescriptor[] _columns, final boolean _dropIfExists)
			throws SQLException {
		if (_dropIfExists) {
			dropTable(_name, true);
		}
		createTable(_name, _columns);
	}

	/**
	 * creates a table
	 */
	static public void createTable(String _name, HsqlColumnDescriptor[] _columns)
			throws SQLException {
		StringBuffer createStatement = new StringBuffer(
				"CREATE CACHED TABLE \"");
		createStatement.append(_name);
		createStatement.append("\" ( ");

		String primaryKeyList = "";

		final HashMap foreignKeys = new HashMap();
		final HashMap foreignKeyRefs = new HashMap();

		final HsqlColumnDescriptor[] columns = _columns;
		for (int i = 0; i < columns.length; ++i) {
			if (i > 0) {
				createStatement.append(", ");
			}

			createStatement.append("\"" + columns[i].getName());
			createStatement.append("\" " + columns[i].getTypeName());

			if (columns[i].isRequired()) {
				createStatement.append(" NOT NULL");
			}

			if (columns[i].isPrimaryKey()) {
				if (primaryKeyList.length() > 0) {
					primaryKeyList += ", ";
				}
				primaryKeyList += "\"" + columns[i].getName() + "\"";
			}

			if (columns[i].isForeignKey()) {
				final String foreignTable = columns[i].getForeignTable();

				String foreignKeysForTable = foreignKeys
						.containsKey(foreignTable) ? (String) foreignKeys
						.get(foreignTable) : "";
				if (foreignKeysForTable.length() > 0) {
					foreignKeysForTable += ", ";
				}
				foreignKeysForTable += "\"" + columns[i].getName() + "\"";
				foreignKeys.put(foreignTable, foreignKeysForTable);

				final StringBuffer foreignKeyRefsForTable = new StringBuffer(
						foreignKeyRefs.containsKey(foreignTable) ? (String) foreignKeyRefs
								.get(foreignTable) : "");
				if (foreignKeyRefsForTable.length() > 0) {
					foreignKeyRefsForTable.append(", ");
				}
				foreignKeyRefsForTable.append("\""
						+ columns[i].getForeignColumn() + "\"");
				foreignKeyRefs.put(foreignTable,
						foreignKeyRefsForTable.toString());
			}
		}

		if (primaryKeyList.length() > 0) {
			createStatement.append(", PRIMARY KEY (");
			createStatement.append(primaryKeyList);
			createStatement.append(')');
		}

		final Set foreignKeyTables = foreignKeys.keySet();
		for (final Iterator foreignKey = foreignKeyTables.iterator(); foreignKey
				.hasNext();) {
			final String foreignTable = (String) foreignKey.next();

			createStatement.append(", FOREIGN KEY (");
			createStatement.append((String) foreignKeys.get(foreignTable));
			createStatement.append(") REFERENCES \"");
			createStatement.append(foreignTable);
			createStatement.append("\"(");
			createStatement.append((String) foreignKeyRefs.get(foreignTable));
			createStatement.append(')');
		}

		createStatement.append(')');

		// System.err.println( createStatement );
		executeSQL(createStatement.toString());
	}


	/**
	 * executes the given SQL statement via the defaultConnection
	 */
	static public void executeSQL(final String statementString)
			throws SQLException {
		final XStatement statement = defaultConnection().createStatement();
		statement.execute(statementString);
	}

	/**
	 * returns a connection to the database
	 *
	 * Multiple calls to this method return the same connection. The
	 * DbaseDatabase object keeps the ownership of the connection, so you don't
	 * need to (and should not) dispose/close it.
	 */
	static public XConnection defaultConnection() throws SQLException {
		if (m_connection == null)
			m_connection = m_databaseDocument.getDataSource().getConnection("",
					"");

		return m_connection;
	}

	/**
	 * closes the database document
	 *
	 * Any CloseVetoExceptions fired by third parties are ignored, and any
	 * reference to the database document is released.
	 */
	static public void close() {
		// close connection
		final XCloseable closeConn = (XCloseable) UnoRuntime.queryInterface(
				XCloseable.class, m_connection != null ? m_connection : null);
		if (closeConn != null) {
			try {
				closeConn.close();
			} catch (SQLException e) {
			}
		}
		m_connection = null;

		// close document
		final com.sun.star.util.XCloseable closeDoc = (com.sun.star.util.XCloseable) UnoRuntime
				.queryInterface(com.sun.star.util.XCloseable.class,
						m_databaseDocument);
		if (closeDoc != null) {
			try {
				closeDoc.close(true);
			} catch (CloseVetoException e) {
			}
		}
		m_databaseDocument = null;
	}

	/**
	 * returns the underlying database document
	 */
	static public XOfficeDatabaseDocument getDatabaseDocument() {
		return m_databaseDocument;
	}

	static public String getDocumentURL() {
		return m_databaseDocumentFile;
	}
}
