package com.fp.dto.query;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Dto de transporte utilizado en la ejecución de consultas invocadas desde el front end, contiene metadata necesaria
 * para armar y ejecutar consultas en la base de datos.
 * 
 * @author Jorge Vaca.
 * @version 2.1
 */
public class DtoQuery implements Serializable {

    private static final long serialVersionUID = 6080115615379062328L;

    /**
     * Nombre del bean, con el cual se va a ejecutar la consulta.
     */
    private String beanname;

    /**
     * Numero de pagina se utiliza para consultar mas de un registro.
     */
    private Integer page = 0;

    /**
     * Numero de registros por pagina.
     */
    private Integer recperpage = 0;

    /**
     * True indica que la consulta espera de respuesrta de 0..n registros.
     */
    private boolean multirecord = false;

    /**
     * String que contiene la lista de campos por el cual se va a ordenar la consula.<br>
     * ejemplo <br>
     * pk.pais ordenado por pais <br>
     * pk.pais,pk.provincia,nombre ordenado por 3 campo <br>
     * nombre desc orden descendente por nombre <br>
     */
    private String orderby;

    /**
     * Lista de filtros con los cuales se arma la sentencia de la consulta.
     */
    private final List<Filter> lfiltros = new ArrayList<Filter>();

    private final List<SubQuery> lSubquery = new ArrayList<SubQuery>();

    /**
     * Crea una instancia de {@link DtoConsulta}.
     * 
     * @param beanname Nombre del bean a consultar.
     * @param mcriterios Map de filtros tipo camo-valor.
     * @throws Exception
     */
    public DtoQuery(String beanname, Map<String, String> mcriterios) throws Exception {
        this.beanname = beanname;
        addCriterios(mcriterios);
    }

    /**
     * Crea una instancia de {@link DtoConsulta}.
     * 
     * @param beanname Nombre del bean a consultar.
     * @param mcriterios Map de filtros tipo camo-valor.
     * @throws Exception
     */
    public DtoQuery(String beanname, Integer page, Integer recperpage, boolean multirecord, Map<String, String> mcriterios) throws Exception {
        this.beanname = beanname;
        this.page = page;
        this.recperpage = recperpage;
        this.multirecord = multirecord;
        addCriterios(mcriterios);
    }

    /**
     * Adiciona criterios a la consulta dado map, campo-valor.
     * 
     * @param mcriterios Map que contiene filtros, campo - valor, al inicio del campo puede estar incluido el criterio.
     * @throws Exception
     */
    public void addCriterios(Map<String, String> mcriterios) throws Exception {
        if (mcriterios == null) {
            return;
        }
        Set<String> s = mcriterios.keySet();
        for (String campo : s) {
            if (mcriterios.get(campo) != "" && mcriterios.get(campo) != null) {
                Filter f = new Filter(campo, mcriterios.get(campo));
                lfiltros.add(f);
            }
        }
    }

    /**
     * Adiciona un filtro a la consulta.
     * 
     * @param filtro Objeto que contiene los datos del filtro a utilizar en la consulta.
     * @throws Exception
     */
    public void addFiltro(Filter filtro) throws Exception {
        lfiltros.add(filtro);
    }

    /**
     * Adiciona un subquery a la consulta.
     * 
     * @param subquery Objeto que contiene los datos de subquery a utilizar en la consulta.
     * @throws Exception
     */
    public void addSubQuery(SubQuery subquery) throws Exception {
        lSubquery.add(subquery);
    }

    /**
     * Entrega el valor de: beanname
     * 
     * @return String
     */
    public String getBeanname() {
        return beanname;
    }

    /**
     * Fija el valor de: beanname
     * 
     * @param Valor a fijar en el atributo.
     */
    public void setBeanname(String beanname) {
        this.beanname = beanname;
    }

    /**
     * Entrega el valor de: orderby
     * 
     * @return String
     */
    public String getOrderby() {
        return orderby;
    }

    /**
     * Fija el valor de: orderby
     * 
     * @param Valor a fijar en el atributo.
     */
    public void setOrderby(String orderby) {
        this.orderby = orderby;
    }

    /**
     * Entrega el valor de: page
     * 
     * @return Integer
     */
    public Integer getPage() {
        return page;
    }

    /**
     * Entrega el valor de: multirecord
     * 
     * @return boolean
     */
    public boolean isMultirecord() {
        return multirecord;
    }

    /**
     * Fija el valor de: multirecord
     * 
     * @param Valor a fijar en el atributo.
     */
    public void setMultirecord(boolean multirecord) {
        this.multirecord = multirecord;
    }

    /**
     * Entrega el valor de: recperpage
     * 
     * @return Integer
     */
    public Integer getRecperpage() {
        return recperpage;
    }

    /**
     * Entrega el valor de: lfiltros
     * 
     * @return List<Filter>
     */
    public List<Filter> getLfilter() {
        return lfiltros;
    }

    /**
     * Entrega el valor de: lSubquery
     * 
     * @return List<SubQuery>
     */
    public List<SubQuery> getlSubquery() {
        return lSubquery;
    }

}
