package org.seasar.extension.jdbc.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

import javax.sql.DataSource;

import org.seasar.extension.jdbc.ValueType;
import org.seasar.extension.jdbc.types.ValueTypes;
import org.seasar.framework.exception.EmptyRuntimeException;
import org.seasar.framework.exception.SQLRuntimeException;
import org.seasar.framework.util.ConnectionUtil;
import org.seasar.framework.util.DataSourceUtil;

/**
 * @author higa
 *
 */
public class BasicHandler {

	private DataSource dataSource_;
	private String sql_;

	public BasicHandler() {
	}

	public DataSource getDataSource() {
		return dataSource_;
	}

	public void setDataSource(DataSource dataSource) {
		dataSource_ = dataSource;
	}

	public String getSql() {
		return sql_;
	}

	public void setSql(String sql) {
		sql_ = sql;
	}

	protected Connection getConnection() {
		if (dataSource_ == null) {
			throw new EmptyRuntimeException("dataSource");
		}
		return DataSourceUtil.getConnection(dataSource_);
	}

	protected PreparedStatement prepareStatement(Connection connection) {
		if (sql_ == null) {
			throw new EmptyRuntimeException("sql");
		}
		return ConnectionUtil.prepareStatement(connection, sql_);
	}

	protected void bindArgs(PreparedStatement ps, Object[] args) {
		if (args == null) {
			return;
		}
		for (int i = 0; i < args.length; ++i) {
			ValueType valueType = ValueTypes.getValueType(args[i]);
			try {
				valueType.bindValue(ps, i + 1, args[i]);
			} catch (SQLException ex) {
				throw new SQLRuntimeException(ex);
			}
		}
	}
	
	protected String getCompleteSql(Object[] args) {
		if (args == null || args.length == 0) {
			return sql_;
		}
		StringBuffer buf = new StringBuffer(200);
		int pos = 0;
		int pos2 = 0;
		int index = 0;
		while (true) {
			pos = sql_.indexOf('?', pos2);
			if (pos > 0) {
				buf.append(sql_.substring(pos2, pos));
				buf.append(getBindVariableText(args[index++]));
				pos2 = pos + 1;
			} else {
				buf.append(sql_.substring(pos2));
				break;
			}
		}
		return buf.toString();
	}
	
	protected String getBindVariableText(Object bindVariable) {
		if (bindVariable instanceof String) {
			return "'" + bindVariable + "'";
		} else if (bindVariable instanceof Number) {
			return bindVariable.toString();
		} else if (bindVariable instanceof Timestamp) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH.mm.ss");
			return "'" + sdf.format((java.util.Date) bindVariable) + "'";
		} else if (bindVariable instanceof java.util.Date) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			return "'" + sdf.format((java.util.Date) bindVariable) + "'";
		} else if (bindVariable == null) {
			return "null";
		} else {
			return "'" + bindVariable.toString() + "'";
		}
	}
}