package com.zuehlke.aicp;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLWarning;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class MyServlet extends HttpServlet {

	public static final String JDBC_URL = "jdbc:postgresql://localhost:5432/test";
	public static final String QUERY = "";
	private static final long serialVersionUID = 1L;
	private static final String USER = "test";
	private static final String PWD = "test";

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
		try {
			writeStandardResponse(response);
			if (request.getParameter("direct") != null) {
				response.getOutputStream().print(query(direct()));
			} else if (request.getParameter("c3p0") != null) {
				response.getOutputStream().print(query(c3p0()));
			} else if (request.getParameter("proxool") != null) {
				response.getOutputStream().print(query(proxool()));
			} else if (request.getParameter("dbcp") != null) {
				response.getOutputStream().print(query(dbcp()));
			} 
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void writeStandardResponse(HttpServletResponse response) throws IOException {
		response.setContentType("text/html");
		response.getOutputStream().println("<ul>");
		response.getOutputStream().println("<li><a href='/ArrayInConnectionPool?direct'>direct</a></li>");
		response.getOutputStream().println("<li><a href='/ArrayInConnectionPool?proxool'>proxool</a></li>");
		response.getOutputStream().println("<li><a href='/ArrayInConnectionPool?c3p0'>c3p0</a></li>");
		response.getOutputStream().println("<li><a href='/ArrayInConnectionPool?dbcp'>dbcp</a></li>");
		response.getOutputStream().println("<ul>");
		response.getOutputStream().println("<h3>Result (9 expected)</h3>");
	}
	
	private String query(Connection conn) {
		StringBuilder out = new StringBuilder();
		try {
			for (SQLWarning warn = conn.getWarnings(); warn != null; warn = warn.getNextWarning()) {
				out.append("SQL Warning:");
				out.append("State  : " + warn.getSQLState());
				out.append("Message: " + warn.getMessage());
				out.append("Error  : " + warn.getErrorCode());
			}
			
			Long[] array = { 1L, 2L };
			PreparedStatement ps = conn.prepareStatement("SELECT * FROM arraySum(?, ?)");
			ps.setLong(1, 3L);
			ps.setArray(2, conn.createArrayOf("bigint", array));
			ps.execute();
			ResultSet rs = ps.getResultSet();
			while (rs.next()) {
				out.append(rs.getString(1));
			}
			rs.close();
			ps.close();
			conn.close();
		} catch (Exception e) {
			out.append(getStackTrace(e));
		}
		return out.toString();
	}
	
	private Connection c3p0() {
		return getJndiDataSource("jdbc/c3p0");
	}
	private Connection proxool() {
		return getJndiDataSource("jdbc/proxool");
	}
	private Connection dbcp() {
		return getJndiDataSource("jdbc/dbcp");
	}

	private Connection getJndiDataSource(String name) {
		try {
			Context initContext = new InitialContext();
			Context envContext = (Context) initContext.lookup("java:/comp/env");
			DataSource ds = (DataSource) envContext.lookup(name);
			return ds.getConnection();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private Connection direct() {
		try {
			Class.forName("org.postgresql.Driver");
			return DriverManager.getConnection(JDBC_URL, USER, PWD);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	  public static String getStackTrace(Throwable aThrowable) {
		    final Writer result = new StringWriter();
		    final PrintWriter printWriter = new PrintWriter(result);
		    aThrowable.printStackTrace(printWriter);
		    String html = result.toString();
		    html = html.replaceAll("\n", "<br />\n");
		    return html;
		  }


}
