package org.jfox.dao;

import java.util.Iterator;

import org.jfox.dao.mapping.ColumnMapping;
import org.jfox.dao.mapping.TableMapping;

/**
 * @author <a href="mailto:yangyong@ufsoft.com.cn">Young Yang</a>
 */

public class SqlUtil {

    public static String generateSelectStatementByPrimaryKey(TableMapping mapping) throws DAOException {
        validateObjectMapping(mapping);
        StringBuffer buffer = new StringBuffer();
        buffer.append("select ");

        Iterator iterator = mapping.getColumnMappings().iterator();
        while(iterator.hasNext()) {
            ColumnMapping fieldMapping = (ColumnMapping) iterator.next();
            if(!fieldMapping.isDisableSet()) {
                buffer.append(fieldMapping.getColumnName());
                if(iterator.hasNext()) {
                    buffer.append(", ");
                }
            }
        }

        buffer.append(" from ");
        buffer.append(mapping.getTableName());
        buffer.append(" where ");
        buffer.append(mapping.getPrimaryKeyColumnName());
        buffer.append(" = ?");
        return buffer.toString();
    }

/*    public static String generateSelectStatementByPrimaryKeys(TableMapping mapping, int primaryKeyCount) throws DAOException {
        if(primaryKeyCount <= 0) {
            throw new DAOException("The primary key count must >=1, current is " + primaryKeyCount);
        }

        validateObjectMapping(mapping);

        StringBuffer buffer = new StringBuffer();
        buffer.append("select ");

        Iterator iterator = mapping.getColumnMappings().iterator();
        while(iterator.hasNext()) {
            ColumnMapping fieldMapping = (ColumnMapping) iterator.next();
            if(!fieldMapping.isDisableSet()) {
                buffer.append(fieldMapping.getColumnName());
                if(iterator.hasNext()) {
                    buffer.append(", ");
                }
            }
        }

        buffer.append(" from ");
        buffer.append(mapping.getTableName());
        buffer.append(" where ");
        buffer.append(mapping.getPrimaryKeyColumnName());
        buffer.append(" in (?");
        for(int i = 1; i < primaryKeyCount; i++) {
            buffer.append(", ?");
        }
        buffer.append(")");
        return buffer.toString();
    }*/

    public static String generateInsertStatement(TableMapping mapping) throws DAOException {
        validateObjectMapping(mapping);
        StringBuffer buffer = new StringBuffer();
        StringBuffer valueBuffer = new StringBuffer();

        buffer.append("insert into ");
        buffer.append(mapping.getTableName());
        buffer.append(" (");

        Iterator iterator = mapping.getColumnMappings().iterator();
        boolean isFirst = true;
        while(iterator.hasNext()) {
            ColumnMapping fieldMapping = (ColumnMapping) iterator.next();
            if(!fieldMapping.isDisableGet() && !fieldMapping.isAutoEvaluated()) {
                if(!isFirst) {
                    buffer.append(", ");
                    valueBuffer.append(", ");
                }
                buffer.append(fieldMapping.getColumnName());
                valueBuffer.append("?");
                isFirst = false;
            }
        }

        buffer.append(") values (");
        buffer.append(valueBuffer.toString());
        buffer.append(')');

        return buffer.toString();
    }

    public static String generateUpdateStatement(TableMapping mapping) throws DAOException {
        validateObjectMapping(mapping);
        validatePrimaryKey(mapping);
        StringBuffer buffer = new StringBuffer();
        buffer.append("update ");
        buffer.append(mapping.getTableName());
        buffer.append(" set ");

        Iterator iterator = mapping.getColumnMappings().iterator();
        boolean isFirst = true;
        while(iterator.hasNext()) {
            ColumnMapping columnMapping = (ColumnMapping) iterator.next();
            if(!columnMapping.isDisableGet() && !columnMapping.isAutoEvaluated()) {
                if(!isFirst) {
                    buffer.append(", ");
                }
                buffer.append(columnMapping.getColumnName());
                buffer.append(" = ? ");
                isFirst = false;
            }
        }

        buffer.append(" where ");
        buffer.append(mapping.getPrimaryKeyColumnName());
        buffer.append(" = ?");

        return buffer.toString();
    }

    public static String generateDeleteStatement(TableMapping mapping) throws DAOException {
        validateObjectMapping(mapping);
        validatePrimaryKey(mapping);

        StringBuffer buffer = new StringBuffer();
        buffer.append("delete from ");
        buffer.append(mapping.getTableName());
        buffer.append(" where ");
        buffer.append(mapping.getPrimaryKeyColumnName());
        buffer.append(" = ?");

        return buffer.toString();

    }

    protected static void validateObjectMapping(TableMapping mapping) throws DAOException {
        if(mapping.getTableName() == null) {
            throw new DAOException("The object mapping contained no table name");
        }
        if(mapping.getMappingClass() == null) {
            throw new DAOException("The object mapping contained no class");
        }
        if(mapping.getMappingColumnSize() == 0) {
            throw new DAOException("The object mapping contained no getter method mappings");
        }
    }

    protected static void validatePrimaryKey(TableMapping mapping) throws DAOException {
        String primaryKey = null;
        primaryKey = mapping.getPrimaryKeyColumnName();

        if(primaryKey == null || primaryKey.trim().equals("")) {
            throw new DAOException("No primary key column name (was null) for object mapping");
        }

        ColumnMapping primaryKeyMapping = mapping.getColumnMapping(mapping.getPrimaryKeyColumnName());
        if(primaryKeyMapping == null) {
            throw new DAOException("No getter method (was null) for primary getter mapping ");
        }

        if(primaryKeyMapping.getColumnName() == null) {
            throw new DAOException("No column name (was null) for primary key getter mapping");
        }
    }
}

