package com.ejie.m62fb.dao.registroVPP;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.m62fb.dao.SQLGenericas;
import com.ejie.m62fb.model.InformacionSuelo;
import com.ejie.m62fb.model.tipos.TipoElemento;

/**
 * InformacionSuelosDaoImpl
 * 
XXXX
 */
@Repository
@Transactional
public class InformacionSueloDaoImpl implements InformacionSueloDao {
	protected static final InformacionSuelo UtilsResultSet = null;

	private JdbcTemplate jdbcTemplate;

	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * StringBuilder initilization value
	 */
	public static final int STRING_BUILDER_INIT = 4096;

	private final RowMapper<InformacionSuelo> rwMap = new RowMapper<InformacionSuelo>() {
		@Override
		public InformacionSuelo mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			InformacionSuelo informacionSuelo = new InformacionSuelo();
			informacionSuelo.setIdM62r20t0(resultSet
					.getBigDecimal("ID_M62R20T0"));
			informacionSuelo.setIdM62r21t0(resultSet
					.getBigDecimal("ID_M62R21T0"));

			informacionSuelo.setNumElemento(resultSet
					.getBigDecimal("NUM_ELEMENTO"));
			TipoElemento tipoElemento = new TipoElemento(
					resultSet.getString("COD_TIPO_ELEM"));
			informacionSuelo.setTipoElemento(tipoElemento);
			informacionSuelo.setCuotaParticipacion(resultSet
					.getBigDecimal("CUOTA_PARTICIPACION"));

			return informacionSuelo;
		}
	};

	/**
	 * Updates a single row in the INFORMACION_SUELO table.
	 * 
	 * @param informacionSuelo
	 *            InformacionSuelo
	 * @return InformacionSuelo
	 */
	@Override
	public InformacionSuelo update(InformacionSuelo informacionSuelo) {
		String query = InformacionSueloDaoSql.SQL_UPDATE;

		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();

		// CuotaParticipacion
		params.add(informacionSuelo.getCuotaParticipacion());
		// AbstractM62FBModel
		SQLGenericas.getParamsAbstractClass(params, informacionSuelo);

		// NumElemento
		params.add(informacionSuelo.getNumElemento());
		// TipoElemento
		params.add(informacionSuelo.getTipoElemento() != null ? informacionSuelo
				.getTipoElemento().getCodTabla() : null);

		// Realizar Update
		this.jdbcTemplate.update(query, params.toArray());

		return informacionSuelo;
	}

	/**
	 * Finds a single row in the M62r12t0 table.
	 * 
	 * @param elemento
	 *            Elemento
	 * @return Elemento
	 */
	@Override
	@Transactional(readOnly = true)
	public InformacionSuelo find(InformacionSuelo informacionSuelo) {
		String query = InformacionSueloDaoSql.SQL_FIND;
		List<InformacionSuelo> elementoList = this.jdbcTemplate.query(query,
				this.rwMap, informacionSuelo.getNumElemento(), informacionSuelo
						.getTipoElemento().getCodTabla());
		return DataAccessUtils.uniqueResult(elementoList);
	}

	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(InformacionSuelo informacionSuelo) {
		StringBuilder query = new StringBuilder(
				InformacionSueloDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(informacionSuelo);
		StringBuilder where = new StringBuilder(
				InformacionSueloDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	@Override
	@Transactional(readOnly = true)
	public boolean existeSolicitudDchoSup(InformacionSuelo informacionSuelo) {
		StringBuilder query = new StringBuilder(
				InformacionSueloDaoSql.SQL_FIND_ALL_COUNT_SOLIC_DCHO_SUP);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(informacionSuelo);
		StringBuilder where = new StringBuilder(
				InformacionSueloDaoSql.SQL_WHERE_SOLIC_DCHO_SUP);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray()) > 0;
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the InformacionSuelo entity
	 * 
	 * @param informacionSuelo
	 *            InformacionSuelo Bean with the criteria values to filter by.
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, ?> getWhereMap(InformacionSuelo informacionSuelo) {

		StringBuilder where = new StringBuilder(
				ElementosDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (informacionSuelo != null
				&& informacionSuelo.getNumElemento() != null) {
			where.append(" AND NUM_ELEMENTO= ?");
			params.add(informacionSuelo.getNumElemento());
		}
		if (informacionSuelo != null
				&& informacionSuelo.getTipoElemento() != null
				&& informacionSuelo.getTipoElemento().getCodTabla() != null
				&& informacionSuelo.getTipoElemento().getCodTabla().trim()
						.length() > 0) {
			where.append(" AND COD_TIPO_ELEM= ?");
			params.add(informacionSuelo.getTipoElemento().getCodTabla());
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}
}