package hiro.yoshioka.sql;

import hiro.yoshioka.util.StringUtil;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DBMSOutput {

	protected Log fLogger = LogFactory.getLog(getClass());
	static String[] EMPTY = new String[0];

	private Connection con = null;

	private int bufferSize = 100 * 1024;

	public DBMSOutput(Connection con) {
		this.con = con;
		String sql = "BEGIN DBMS_OUTPUT.ENABLE(?); END;";
		PreparedStatement stmt = null;
		try {
			stmt = con.prepareStatement(sql);
			stmt.setInt(1, bufferSize);
			stmt.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * DBMS_OUTPUT.GET_LINEを繰り返し呼び出してバッファの内容を返す
	 */
	public String[] getLines() {
		StringBuffer sql = new StringBuffer();
		sql.append("BEGIN DBMS_OUTPUT.GET_LINE(?, ?); END;\n");
		CallableStatement stmt = null;
		try {
			stmt = con.prepareCall(sql.toString());
			ArrayList<String> retList = new ArrayList<String>();
			stmt.registerOutParameter(1, Types.VARCHAR);
			stmt.registerOutParameter(2, Types.INTEGER);
			while (true) {
				stmt.execute();
				if (stmt.getInt(2) == 1) {
					break;
				}
				String str = stmt.getString(1);
				if (str.replaceAll("\r|\n", StringUtil.EMPTY_STRING).trim()
						.length() == 0) {
					break;
				}
				retList.add(str);
			}
			if (retList.size() > 0) {
				retList.add(0, String.format(
						"----- DBMS OUTPUT TIME[%tH:%<tM:%<tS] START -----",
						new Date()));
				retList.add("----- DBMS OUTPUT END -----");
			}
			return retList.toArray(new String[retList.size()]);
		} catch (SQLException e) {
			fLogger.warn(e);
			return EMPTY;
		} finally {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
