/*
 * This file is part of Nuts Framework.
 * Copyright(C) 2009-2012 Nuts Develop Team.
 *
 * Nuts Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License any later version.
 * 
 * Nuts Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.aws.dao;

import java.util.List;

import nuts.core.orm.dao.AbstractModelDAO;
import nuts.core.orm.dao.DataAccessException;
import nuts.core.orm.dao.DataAccessSession;
import nuts.core.orm.dao.DataHandler;
import nuts.core.sql.criterion.SqlQueryParameter;

/**
 * @param <T> model type
 * @param <E> model example type
 */
public abstract class AwsModelDAO<T, E extends SqlQueryParameter> extends AbstractModelDAO<T, E> {
	/**
	 * Constructor
	 */
	public AwsModelDAO() {
		super();
	}

	/**
	 * Constructor
	 *
	 * @param dataAccessSession the dataAccessSession to set
	 */
	public AwsModelDAO(DataAccessSession dataAccessSession) {
		super(dataAccessSession);
	}

	/**
	 * @return the AwsDataAccessClient
	 */
	public AwsDataAccessClient getAwsDataAccessClient() {
		return ((AwsDataAccessClient)getDataAccessClient());
	}

	/**
	 * @return the AwsDataAccessSession
	 */
	public AwsDataAccessSession getAwsDataAccessSession() {
		return ((AwsDataAccessSession)getDataAccessSession());
	}

	/**
	 * @return model id
	 */
	protected abstract String getModelId();
	
	/**
	 * exists
	 * 
	 * @param key T
	 * @return T
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public boolean exists(T key) throws DataAccessException {
		return getAwsDataAccessSession().exists(getModelId(), key);
	}
	
	/**
	 * countByExample
	 * 
	 * @param example E
	 * @return count
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int countByExample(E example) throws DataAccessException {
		return getAwsDataAccessSession().countByExample(getModelId(), example);
	}

	/**
	 * selectByPrimaryKey
	 * 
	 * @param key T
	 * @return T
	 * @throws DataAccessException if a data access error occurs
	 */ 
	@SuppressWarnings("unchecked")
	public T selectByPrimaryKey(T key) throws DataAccessException {
		return (T)(getAwsDataAccessSession().selectByPrimaryKey(getModelId(), key));
	}

	/**
	 * selectByExampleWithDataHandler
	 * 
	 * @param example E
	 * @param dataHandler data handler
	 * @return data count
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int selectByExampleWithDataHandler(E example, DataHandler<T> dataHandler) throws DataAccessException {
		return getAwsDataAccessSession().selectByExampleWithDataHandler(getModelId(), example, dataHandler);
	}

	/**
	 * selectByExample
	 * 
	 * @param example E
	 * @return list of T 
	 * @throws DataAccessException if a data access error occurs
	 */ 
	@SuppressWarnings("unchecked")
	public List<T> selectByExample(E example) throws DataAccessException {
		return getAwsDataAccessSession().selectByExample(getModelId(), example);
	}

	/**
	 * if (exists(data)) { updateByPrimaryKey(data); } else { insert(data}; }
	 * 
	 * @param data T
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public void save(T data) throws DataAccessException {
		getAwsDataAccessSession().save(getModelId(), data);
	}
	
	/**
	 * insert
	 * 
	 * @param data T
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public void insert(T data) throws DataAccessException {
		getAwsDataAccessSession().insert(getModelId(), data);
	}

	/**
	 * deleteByPrimaryKey
	 * 
	 * @param key T
	 * @return count of deleted records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int deleteByPrimaryKey(T key) throws DataAccessException {
		return getAwsDataAccessSession().deleteByPrimaryKey(getModelId(), key);
	}

	/**
	 * deleteByExample
	 * 
	 * @param example E
	 * @return count of deleted records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int deleteByExample(E example) throws DataAccessException {
		return getAwsDataAccessSession().deleteByExample(getModelId(), example);
	}

	/**
	 * updateByPrimaryKey
	 * 
	 * @param data T
	 * @return count of updated records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int updateByPrimaryKey(T data) throws DataAccessException {
		return getAwsDataAccessSession().updateByPrimaryKey(getModelId(), data);
	}

	/**
	 * updateByPrimaryKeySelective (ignore null properties)
	 * 
	 * @param data T
	 * @return count of updated records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int updateByPrimaryKeySelective(T data) throws DataAccessException {
		return getAwsDataAccessSession().updateByPrimaryKeySelective(getModelId(), data);
	}

	/**
	 * updateByExample
	 * 
	 * @param data T
	 * @param example E
	 * @return count of updated records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int updateByExample(T data, E example) throws DataAccessException {
		return getAwsDataAccessSession().updateByExample(getModelId(), data, example);
	}

	/**
	 * updateByExampleSelective (ignore null properties)
	 * 
	 * @param data T
	 * @param example E
	 * @return count of updated records
	 * @throws DataAccessException if a data access error occurs
	 */ 
	public int updateByExampleSelective(T data, E example) throws DataAccessException {
		return getAwsDataAccessSession().updateByExampleSelective(getModelId(), data, example);
	}
}
