/*
 * 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.empire.spring;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.sql.DataSource;

import org.apache.empire.db.DBColumnExpr;
import org.apache.empire.db.DBCommand;
import org.apache.empire.db.DBReader;
import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBRecordData;
import org.apache.empire.db.DBRowSet;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.exceptions.RecordNotFoundException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;

/**
 * This class simplifies database access methods with Empire. Database queries
 * are executed with the help of callback interfaces, while hides connection
 * handling from the developer. Only the query logic has to be implemented and
 * leave getting and releasing the connection to the template.
 * 
 * Some methods (delete, update) delegates to DBRecord, DBDatabase and DBCommand
 * methods while hiding connection handling from developers.
 * 
 * This class is working with a wrapped JdbcTemplate, so either jdbcTemplate or
 * dataSource must be set.
 * 
 * Allows customization of creating DBReader and DBRecord instances through
 * ObjectFactories.
 * 
 * This class is based on {@link org.springframework.jdbc.core.JdbcTemplate}.
 * 
 *
 */

public class EmpireTemplate implements InitializingBean {

	/** Wrapped JdbcTemplate instance */
	private JdbcTemplate jdbcTemplate;

	/** Factory to create a new DBReader instance, by default returns DBReader */
	private ObjectFactory<DBReader> readerFactory = new ObjectFactory<DBReader>() {

		@Override
		public DBReader getObject() throws BeansException {
			return new DBReader();
		}

	};

	/** Factory to create a new DBRecord instance, by default returns DBRecord */
	private ObjectFactory<DBRecord> recordFactory = new ObjectFactory<DBRecord>() {

		@Override
		public DBRecord getObject() throws BeansException {
			return new DBRecord();
		}

	};

	/** Default constructor */
	public EmpireTemplate() {
		super();
	}

	/**
	 * Setting a custom ObjectFactory to allow custom DBRecord create with
	 * newRecord().
	 * 
	 * @param recordFactory
	 */

	public void setDBRecordFactory(ObjectFactory<DBRecord> recordFactory) {
		this.recordFactory = recordFactory;
	}

	/**
	 * Setting a custom DBRecord class to use in newRecord().
	 * 
	 * @param recordClass
	 *            the class which extends DBRecord.class
	 */
	public void setDBRecordClass(final Class<? extends DBRecord> recordClass) {
		this.recordFactory = new ObjectFactory<DBRecord>() {

			@Override
			public DBRecord getObject() throws BeansException {
				try {
					return recordClass.newInstance();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		};
	}

	/**
	 * Setting a custom ObjectFactory to allow custom DBReaders to use in
	 * queries.
	 * 
	 * @param readerFactory
	 */

	public void setDBReaderFactory(ObjectFactory<DBReader> readerFactory) {
		this.readerFactory = readerFactory;
	}

	/**
	 * Setting a custom DBReader class to use in queries.
	 * 
	 * @param readerClass
	 *            the class which extends DBReader.class
	 */
	public void setDBReaderClass(final Class<? extends DBReader> readerClass) {
		this.readerFactory = new ObjectFactory<DBReader>() {

			@Override
			public DBReader getObject() throws BeansException {
				try {
					return readerClass.newInstance();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		};
	}

	/** Setting the wrapped JdbcTemplate */
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public JdbcTemplate getJdbcTemplate() {
		return this.jdbcTemplate;
	}

	/** Setting the datasource */
	public final void setDataSource(DataSource dataSource) {
		if (this.jdbcTemplate == null
				|| dataSource != this.jdbcTemplate.getDataSource()) {
			this.jdbcTemplate = new JdbcTemplate(dataSource);
			this.jdbcTemplate.afterPropertiesSet();
		}
	}

	public void afterPropertiesSet() {
		if (getJdbcTemplate() == null) {
			throw new IllegalArgumentException(
					"Property 'jdbcTemplate' is required, either jdbcTemplate or dataSource must be set.");
		}

	}

	/**
	 * Executes a given DBCommand, mapping each row to a Java object via a
	 * DBRecordMapper.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param recordMapper
	 *            the mapper which maps each DBRecordData to a Java object
	 * @return the extracted list
	 */
	public <K> List<K> query(final DBCommand cmd,
			final DBRecordMapper<K> recordMapper) {
		return query(cmd, new DbRecordMapperExtractor<K>(recordMapper));

	}

	/**
	 * Executes a given DBCommand, mapping a single row to a Java object using
	 * the provided DBRecordMapper.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param recordMapper
	 *            the DBRecordMapper to map
	 * @return the single Object
	 * @throws IncorrectResultSizeDataAccessException
	 *             if more than one result object has been found
	 */
	public <K> K queryForObject(final DBCommand cmd,
			final DBRecordMapper<K> recordMapper) {

		return DataAccessUtils.uniqueResult(query(cmd, recordMapper));

	}

	/**
	 * Executes a given DBCommand, mapping a single column to a Java object
	 * using on DBRecordData.getValue() method.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @return the extracted list
	 */
	public List<Object> queryForList(final DBCommand cmd, final DBColumnExpr col) {
		class SingleValueMapper implements DBRecordMapper<Object> {

			@Override
			public Object mapRecord(DBRecordData record, int rowNum) {
				return record.getValue(col);
			}

		}
		return query(cmd, new SingleValueMapper());

	}

	/**
	 * Executes a given DBCommand, mapping a single column to a single Long. If
	 * the value in the database is null, defaultValue is returned.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @param defaultValue
	 *            the value to return in case of the database value is null
	 * @return the single Long value
	 * @throws IncorrectResultSizeDataAccessException
	 *             if more than one result object has been found
	 */
	public Long queryForLong(final DBCommand cmd, final DBColumnExpr col,
			Long defaultValue) {
		return DataAccessUtils.uniqueResult(queryForLongList(cmd, col,
				defaultValue));
	}

	/**
	 * Executes a given DBCommand, extracting a single column to a List of Long.
	 * If the value in the database is null, defaultValue is added to the list.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @param defaultValue
	 *            the value to return in case of the database value is null
	 * @return the extracted list
	 */
	public List<Long> queryForLongList(final DBCommand cmd,
			final DBColumnExpr col, final Long defaultValue) {
		class SingleLongMapper implements DBRecordMapper<Long> {

			@Override
			public Long mapRecord(DBRecordData record, int rowNum) {
				return record.isNull(col) ? defaultValue : record.getLong(col);
			}

		}
		return query(cmd, new SingleLongMapper());

	}

	/**
	 * Executes a given DBCommand, mapping a single column to a single Integer.
	 * If the value in the database is null, defaultValue is returned.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @param defaultValue
	 *            the value to return in case of the database value is null
	 * @return the single Integer value
	 * @throws IncorrectResultSizeDataAccessException
	 *             if more than one result object has been found
	 */
	public Integer queryForInteger(final DBCommand cmd, final DBColumnExpr col,
			Integer defaultValue) {
		return DataAccessUtils.uniqueResult(queryForIntegerList(cmd, col,
				defaultValue));
	}

	/**
	 * Executes a given DBCommand, extracting a single column to a List of
	 * Integers. If the value in the database is null, defaultValue is added to
	 * the list.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @param defaultValue
	 *            the value to return in case of the database value is null
	 * @return the extracted list
	 */
	public List<Integer> queryForIntegerList(final DBCommand cmd,
			final DBColumnExpr col, final Integer defaultValue) {
		class SingleIntegerMapper implements DBRecordMapper<Integer> {

			@Override
			public Integer mapRecord(DBRecordData record, int rowNum) {
				return record.isNull(col) ? defaultValue : record.getInt(col);
			}

		}
		return query(cmd, new SingleIntegerMapper());
	}

	/**
	 * Executes a given DBCommand, mapping a single column to a single String.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @return the single String value
	 * @throws IncorrectResultSizeDataAccessException
	 *             if more than one result object has been found
	 */
	public String queryForString(final DBCommand cmd, final DBColumnExpr col) {
		return DataAccessUtils.uniqueResult(queryForStringList(cmd, col));
	}

	/**
	 * Executes a given DBCommand, extracting a single column to a List of
	 * Strings.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param col
	 *            the column to map
	 * @return the extracted list
	 */
	public List<String> queryForStringList(final DBCommand cmd,
			final DBColumnExpr col) {
		class SingleStringMapper implements DBRecordMapper<String> {

			@Override
			public String mapRecord(DBRecordData record, int rowNum) {
				return record.getString(col);
			}

		}
		return query(cmd, new SingleStringMapper());
	}

	/**
	 * Executes a given DBCommand and handles the DBReader with the provided
	 * DBReaderExtractor.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param readerExtractor
	 * @return the result returned by the readerExtractor
	 */
	public <K> K query(final DBCommand cmd,
			final DBReaderExtractor<K> readerExtractor) {

		class QueryCallback implements ConnectionCallback<K> {
			public K doInConnection(Connection connection) throws SQLException,
					DataAccessException {
				return query(connection, cmd, readerExtractor);
			}
		}
		return getJdbcTemplate().execute(new QueryCallback());

	}

	/**
	 * Executes a given DBCommand and handles each row of the DBReader with the
	 * provided DBRecordCallbackHandler.
	 * 
	 * @param cmd
	 *            the DBCommand to execute
	 * @param recordCallbackHandler
	 */
	public void query(final DBCommand cmd,
			final DBRecordCallbackHandler recordCallbackHandler) {
		query(cmd, new DbRecordCallbackHandlerExtractor(recordCallbackHandler));
	}

	/**
	 * Deletes a given record from the database. Calls
	 * DBRecord.delete(connection).
	 * 
	 * @see org.apache.empire.db.DBRecord#delete(Connection)
	 * @param record
	 *            to delete
	 */
	public void deleteRecord(final DBRecord record) {

		class DeleteRecordCallback implements ConnectionCallback<Object> {
			public Object doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				record.delete(connection);
				return null;
			}
		}
		getJdbcTemplate().execute(new DeleteRecordCallback());

	}

	/**
	 * Deletes a record from a table with a given single primary key.
	 * 
	 * @param table
	 *            the table to delete from
	 * @param key
	 *            the primary key
	 */

	public void deleteRecord(final DBTable table, final Object key) {
		deleteRecord(table, new Object[] { key });
	}

	/**
	 * Deletes a record from a table with a given multiple primary key. Calls
	 * DBTable.deleteRecord(Object[], Connection).
	 * 
	 * @see org.apache.empire.db.DBTable.deleteRecord(Object[], Connection)
	 * @param table
	 *            the table to delete from
	 * @param keys
	 *            the primary keys array
	 */
	public void deleteRecord(final DBTable table, final Object[] keys) {

		class DeleteRecordCallback implements ConnectionCallback<Object> {
			public Object doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				table.deleteRecord(keys, connection);
				return null;
			}
		}
		getJdbcTemplate().execute(new DeleteRecordCallback());

	}

	/**
	 * Updates the record and saves all changes in the database. Calls
	 * DBRecord.update(connection).
	 *
	 * @see org.apache.empire.db.DBRecord#update(Connection)
	 * @param record
	 *            to update
	 * @return the updated record
	 */
	public DBRecord updateRecord(final DBRecord record) {

		class UpdateRecordCallback implements ConnectionCallback<DBRecord> {
			public DBRecord doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				record.update(connection);
				return record;
			}
		}

		return getJdbcTemplate().execute(new UpdateRecordCallback());

	}

	/**
	 * Executes an Update statement from a command object. This method delegates
	 * to DBDatabase.executeUpdate(cmd, connection), getting the DBDatabase
	 * instance from the DBCOmmand object.
	 *
	 * @see org.apache.empire.db.DBDatabase#executeUpdate(DBCommand, Connection)
	 * 
	 * @param cmd
	 *            the command object containing the update command
	 * @return the number of records that have been updated with the supplied
	 *         statement
	 */
	public int executeUpdate(final DBCommand cmd) {

		class UpdateRecordCallback implements ConnectionCallback<Integer> {
			public Integer doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				return cmd.getDatabase().executeUpdate(cmd, connection);
			}
		}

		return getJdbcTemplate().execute(new UpdateRecordCallback());

	}

	/**
	 * Executes a Delete statement from a command object. This method delegates
	 * to DBDatabase.executeDelete(cmd, connection), getting the DBDatabase
	 * instance from the DBCOmmand object.
	 *
	 * @see org.apache.empire.db.DBDatabase#executeDelete(DBCommand, Connection)
	 * 
	 * @param cmd
	 *            the command object containing the delete command
	 * @return the number of records that have been deleted with the supplied
	 *         statement
	 */
	public int executeDelete(final DBTable table, final DBCommand cmd) {

		class DeleteRecordCallback implements ConnectionCallback<Integer> {
			public Integer doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				return cmd.getDatabase().executeDelete(table, cmd, connection);
			}
		}

		return getJdbcTemplate().execute(new DeleteRecordCallback());

	}

	/**
	 * Executes an Insert statement from a command object. This method delegates
	 * to DBDatabase.executeInsert(cmd, connection), getting the DBDatabase
	 * instance from the DBCOmmand object.
	 *
	 * @see org.apache.empire.db.DBDatabase#executeInsert(DBCommand, Connection)
	 * 
	 * @param cmd
	 *            the command object containing the insert command
	 * @return the number of records that have been inserted with the supplied
	 *         statement
	 */
	public int executeInsert(final DBCommand cmd) {

		class InsertRecordCallback implements ConnectionCallback<Integer> {
			public Integer doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				return cmd.getDatabase().executeInsert(cmd, connection);
			}
		}

		return getJdbcTemplate().execute(new InsertRecordCallback());

	}

	/**
	 * Helper method to an create a DBRecord instance. Can be customized through
	 * setRecordFactory or setRecordClass methods.
	 *
	 * @param table
	 *            the table
	 * @return the new DBRecord instance
	 */
	public DBRecord newRecord(final DBRowSet table) {
		DBRecord record = this.recordFactory.getObject();
		record.create(table);
		return record;
	}

	/**
	 * Opens a DBRecord instance with the given multiple primary keys. In
	 * contrast of getRecord(DBRowSet, Object) this method throws
	 * RecordNotFoundExpcetion if matching record exists.
	 *
	 * @param table
	 *            the table to read the record from
	 * @param key
	 *            the primary key
	 * @return the DBRecord instance, never null
	 * @throws org.apache.empire.db.exceptions.RecordNotFoundException
	 *             in case of the record not found
	 */
	public DBRecord openRecord(final DBRowSet table, final Object key) {
		return openRecord(table, new Object[] { key });
	}

	/**
	 * Opens a DBRecord instance with the given multiple primary keys. In
	 * contrast of getRecord(DBRowSet, Object[]) this method throws
	 * RecordNotFoundExpcetion if matching record exists.
	 *
	 * @param table
	 *            the table to read the record from
	 * @param keys
	 *            the primary key array
	 * @return the DBRecord instance, never null
	 * @throws org.apache.empire.db.exceptions.RecordNotFoundException
	 *             in case of the record not found
	 */
	public DBRecord openRecord(final DBRowSet table, final Object[] keys) {

		class ReadRecordCallback implements ConnectionCallback<DBRecord> {
			public DBRecord doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				DBRecord record = EmpireTemplate.this.recordFactory.getObject();
				record.read(table, keys, connection);
				return record;
			}
		}

		return getJdbcTemplate().execute(new ReadRecordCallback());

	}

	/**
	 * Opens a DBRecord instance with the given single primary key. In contrast
	 * of openRecord(DBRowSet, Object) this method returns null if no matching
	 * record exists.
	 *
	 * @param table
	 *            the table to read the record from
	 * @param key
	 *            the primary key
	 * @return the DBRecord instance, can be null
	 */
	public DBRecord getRecord(final DBRowSet table, final Object key) {
		return openRecord(table, new Object[] { key });
	}

	/**
	 * Opens a DBRecord instance with the given multiple primary keys. In
	 * contrast of openRecord(DBRowSet, Object[]) this method returns null if no
	 * matching record exists.
	 *
	 * @param table
	 *            the table to read the record from
	 * @param keys
	 *            the primary keys array
	 * @return the DBRecord instance, can be null
	 */
	public DBRecord getRecord(final DBRowSet table, final Object[] keys) {

		class ReadRecordCallback implements ConnectionCallback<DBRecord> {
			public DBRecord doInConnection(Connection connection)
					throws SQLException, DataAccessException {
				DBRecord record = EmpireTemplate.this.recordFactory.getObject();
				try {
					record.read(table, keys, connection);
				} catch (RecordNotFoundException e) {
					return null;
				}
				return record;
			}
		}

		return getJdbcTemplate().execute(new ReadRecordCallback());

	}

	/**
	 * Executes a given DBCommand query and maps each row to Class<T> object
	 * using DBReader.getBeanList method.
	 * 
	 * @see org.apache.empire.db.DBReader.getBeanList(C, Class<T>, int)
	 * 
	 * @param cmd
	 *            the query command
	 * @param c
	 *            the collection to add the objects to
	 * @param t
	 *            the class type of the objects in the list
	 * @param maxCount
	 *            the maximum number of objects
	 * 
	 * @return the list of T
	 */
	public <C extends Collection<T>, T> C queryForBeanList(final DBCommand cmd,
			final C c, final Class<T> t, final int maxCount) {

		class GetBeanListCallback implements DBReaderExtractor<C> {

			@Override
			public C process(DBReader reader) {
				return reader.getBeanList(c, t, maxCount);
			}
		}

		return query(cmd, new GetBeanListCallback());

	}

	/**
	 * Executes a given DBCommand query and maps each row to Class<T> object
	 * using DBReader.getBeanList method.
	 * 
	 * @see org.apache.empire.db.DBReader.getBeanList(Class<T>, int)
	 * 
	 * @param cmd
	 *            the query command
	 * @param t
	 *            the class type of the objects in the list
	 * @param maxCount
	 *            the maximum number of objects
	 * 
	 * @return the list of T
	 */
	public <T> List<T> queryForBeanList(DBCommand cmd, Class<T> t, int maxItems) {
		return queryForBeanList(cmd, new ArrayList<T>(), t, maxItems);
	}

	/**
	 * Executes a given DBCommand query and maps each row to Class<T> object
	 * using DBReader.getBeanList method.
	 * 
	 * @see org.apache.empire.db.DBReader.getBeanList(Class<T>)
	 * 
	 * @param cmd
	 *            the query command
	 * @param t
	 *            the class type of the objects in the list
	 * 
	 * @return the list of T
	 */

	public <T> List<T> queryForBeanList(DBCommand cmd, Class<T> t) {
		return queryForBeanList(cmd, t, -1);
	}

	/**
	 * Executes a given DBCommand query and maps a single row to Class<T> object
	 * using DBReader.getBeanList method.
	 * 
	 * @param cmd
	 *            the query command
	 * @param t
	 *            the class type of the object to return
	 * 
	 * @return the list of T
	 * @throws IncorrectResultSizeDataAccessException
	 *             if more than one result object has been found
	 */
	public <T> T queryForBean(DBCommand cmd, Class<T> t) {
		return DataAccessUtils.uniqueResult(queryForBeanList(cmd, t, -1));
	}

	/**
	 * Executes a ConnectionCallback. Delegates to the underlying JdbcTemplate.
	 * 
	 * @see 
	 *      org.springframework.jdbc.core.JdbcTemplate.execute(ConnectionCallback
	 *      <K>)
	 * 
	 * @param connectionCallback
	 * @return arbitrary object
	 */
	public <K> K execute(ConnectionCallback<K> connectionCallback) {
		return getJdbcTemplate().execute(connectionCallback);
	}

	private <K> K query(Connection connection, DBCommand command,
			DBReaderExtractor<K> callback) {
		DBReader reader = newDBReader();
		try {
			reader.open(command, connection);

			return callback.process(reader);

		} finally {
			reader.close();
		}
	}

	/**
	 * Creates a new DBReader instance from the readerFactory;
	 * 
	 * @return DBReader instance
	 */

	private DBReader newDBReader() {

		return this.readerFactory.getObject();
	}

	private static class DbRecordCallbackHandlerExtractor implements
			DBReaderExtractor<Object> {

		private final DBRecordCallbackHandler rowCallbackHandler;

		public DbRecordCallbackHandlerExtractor(
				DBRecordCallbackHandler rowCallbackHandler) {
			Assert.notNull(rowCallbackHandler, "RowCallbackHandler is required");
			this.rowCallbackHandler = rowCallbackHandler;
		}

		// @Override
		public Object process(DBReader reader) {
			try {
				while (reader.moveNext()) {
					this.rowCallbackHandler.processRecord(reader);
				}
				return null;
			} finally {
				reader.close();
			}
		}

	}

	private static class DbRecordMapperExtractor<K> implements
			DBReaderExtractor<List<K>> {

		private final DBRecordMapper<K> dataReader;

		public DbRecordMapperExtractor(DBRecordMapper<K> rowMapper) {
			Assert.notNull(rowMapper, "DataReader is required");
			this.dataReader = rowMapper;
		}

		// @Override
		public List<K> process(DBReader reader) {
			try {
				List<K> results = new ArrayList<K>();
				int rowNum = 0;

				while (reader.moveNext()) {
					results.add(this.dataReader.mapRecord(reader, rowNum));
					rowNum++;
				}

				return results;

			} finally {
				reader.close();
			}
		}

	}

}
