package com.fp.hbm.bgenerator;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.ScrollableResults;

import com.fp.hbm.helper.HqlStatementHQL;
import com.fp.hbm.helper.PersistenceHelperHQL;
import com.fp.hbm.helper.PersistenceManagerHQL;
import com.fp.persistence.commondb.exception.CommondbException;

/**
 * 
 * @author Jorge Vaca
 * @version 2.1
 */
public class HBMapper {

    private List<AbstractMapper> tables;

    private static String path = "D:/workSpace/sources/base/persistence";
    		//"D:/app/comaco/sources/base/persistence";

    private String soucePath = "/java/";

    private String xmlPath = "/resources/";

    private MappingType type;

    public HBMapper(MappingType pType) {
        type = pType;
    }

    public HBMapper(String pPackageBase, MappingType pType, String... sTables) throws HibernateException, CommondbException, ParseException,
            InstantiationException, IllegalAccessException, ClassNotFoundException {
        this(pType);
        tables = new ArrayList<AbstractMapper>();
        for (String table : sTables) {
            AbstractMapper m = type.getMapper();
            m.setParent(this);
            m.setTable(table.toUpperCase());
            m.setPackageBase(pPackageBase);
            m.setEntity(table.substring(5));
            tables.add(m);
        }
    }

    public HBMapper(String pPackageBase, MappingType pType, List<String> sTables) throws HibernateException, CommondbException, ParseException,
            InstantiationException, IllegalAccessException, ClassNotFoundException {
        this(pType);
        tables = new ArrayList<AbstractMapper>();
        for (String table : sTables) {
            AbstractMapper m = type.getMapper();
            m.setParent(this);
            m.setTable(table.toUpperCase());
            m.setPackageBase(pPackageBase);
            m.setEntity(table.substring(5));

            tables.add(m);
        }
    }

    public List<String> process() {
        List<String> data = new ArrayList<String>();
        for (AbstractMapper mapper : tables) {
            try {
                if (mapper.inmanual) {
                    data.add("BEAN no generado tiene metodos de consulta tabla ==> " + mapper.table + " <== Adicione campos manualmente.");
                    continue;
                }
                mapper.safeEntity();
                data.add("BEAN Generado OK para la tabla " + mapper.table);
            } catch (Exception e) {
                e.printStackTrace();
                data.add("BEAN No Generado para la tabla " + mapper.table + " " + e.getMessage());
            }
        }
        return data;
    }

    /**
     * Metodo que se encarga de generar bean's, para generar mas de un bean, separe con coma los nombres de las tablas.
     * 
     * @param args
     */
    public static void main(String[] args) {
        try {
            PersistenceHelperHQL.setSession(PersistenceManagerHQL.getInstance().getSession());
            try {
                HBMapper m = new HBMapper("com.fp.persistence", MappingType.ANN, "TARMVENTAARMATEM");
                m.setPath(HBMapper.path);
                List<String> data = m.process();
                for (String string : data) {
                    System.out.println(string);
                }
            } finally {
                PersistenceHelperHQL.getSession().close();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void maintotal(String[] args) {
        try {
            PersistenceHelperHQL.setSession(PersistenceManagerHQL.getInstance().getSession());
            try {
                /*
                 * ScrollableResults rs = getTables(); if (rs != null) { while (rs.next()) { Object[] obj = rs.get();
                 * String table = (String) obj[0]; System.out.println("Generando ==>" + table); HBMapper m = new
                 * HBMapper("com.fp.persistence", MappingType.ANN, table);
                 * m.setPath("D:\\work\\flip\\sources\\base\\persistence"); List<String> data = m.process(); for (String
                 * string : data) { System.out.println(string); } } }
                 */
            } finally {
                PersistenceHelperHQL.getSession().close();
            }
        } catch (Throwable e) {
            e.printStackTrace(System.err);
        }
    }

    /**
     * Entrega una lista tablas a generar beans.
     * 
     * @return ScrollableResults
     * @throws Exception
     */
    private static ScrollableResults getTables() throws Exception {
        SQLQuery qry = PersistenceHelperHQL.getSession().createSQLQuery("select tname from tgeneentity");
        ScrollableResults rs = null;
        rs = qry.scroll();
        return rs;
    }

    @SuppressWarnings("unchecked")
    public List availableEntities() throws HibernateException, CommondbException, ParseException {
        return this.availableEntities(null);
    }

    @SuppressWarnings("unchecked")
    public List availableEntities(String pCriteria) throws CommondbException, HibernateException, ParseException {
        String hql = "select p.pk.tname,concat(concat(p.pac,'.'),p.pk.entity) from TEntity p where p.pk.tname like :criteria order by p.pk.tname";
        HqlStatementHQL stm = new HqlStatementHQL(hql);
        stm.setString("criteria", ((pCriteria == null) ? "" : pCriteria) + "%");
        return stm.getList();
    }

    public void setPath(String path) {
        HBMapper.path = path;
    }

    public String getPath() {
        return HBMapper.path;
    }

    public void setSoucePath(String soucePath) {
        this.soucePath = soucePath;
    }

    public String getSoucePath() {
        return soucePath;
    }

    public void setXmlPath(String xmlPath) {
        this.xmlPath = xmlPath;
    }

    public String getXmlPath() {
        return xmlPath;
    }

    public MappingType getType() {
        return type;
    }

    public void setType(MappingType pType) {
        type = pType;
    }
}
