package hiro.yoshioka.sql.resource.view.action;

import hiro.yoshioka.sdh.BindObject;
import hiro.yoshioka.sql.engine.CallRequest;
import hiro.yoshioka.sql.engine.Request;
import hiro.yoshioka.sql.engine.RequestAdaptor;
import hiro.yoshioka.sql.engine.SQLOperationType;
import hiro.yoshioka.sql.engine.SQLServerThread;
import hiro.yoshioka.sql.params.ConnectionProperties;
import hiro.yoshioka.sql.params.Parameter;
import hiro.yoshioka.sql.resource.IDBColumn;
import hiro.yoshioka.sql.resource.IDBTable;
import hiro.yoshioka.sql.resource.view.DBResourceTreeViewer;
import hiro.yoshioka.sql.util.FunctionInputDialog;
import hiro.yoshioka.sql.util.SQLUtil2;
import hiro.yoshioka.sql.util.SqlKeyHighlightDialog;
import hiro.yoshioka.util.SQLUtil;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class FunctionExecuteAction extends Action implements
		ISelectionChangedListener {
	protected DBResourceTreeViewer fView;
	private Shell shell;
	private Display display;
	private IDBTable procedure;
	Log fLogger = LogFactory.getLog(getClass());

	boolean isFnctionOrProcedure;

	public FunctionExecuteAction(DBResourceTreeViewer view, IDBTable procedure) {
		super("Execute Function", Action.AS_PUSH_BUTTON);
		fView = view;
		this.procedure = procedure;

		setEnabled(false);
	}

	@Override
	public void run() {
		fView.refreshTableColumnsOnTree(procedure, false);

		this.shell = fView.getTree().getShell();
		this.display = this.shell.getDisplay();
		FunctionInputDialog dialog = new FunctionInputDialog(this.shell,
				procedure);
		if (FunctionInputDialog.OK == dialog.open()) {
			String[] inputs = dialog.getInputValues();
			fLogger.info("\n----- INPUTS PARAMETERS -----");
			for (int i = 0; i < inputs.length; i++) {
				fLogger.info("  [" + (i + 1) + "] [" + inputs[i] + "]");
			}

			IDBColumn[] cols = procedure.getColumns();
			String sqls = SQLUtil2.createCallableSql(procedure);
			CallRequest request = new CallRequest(sqls,
					fView.getConnectionPropertiesOf(this.procedure));
			for (int i = 0, inIdx = 0, index = 1; i < cols.length; i++, index++) {
				if (cols[i].isColumnIn() || cols[i].isColumnInOut()) {
					BindObject bo = null;
					if (cols[i].getDataType().isTime()) {
						Time date = SQLUtil.getTime(inputs[inIdx++]);
						bo = new BindObject(date, cols[i].getDataType());
					} else if (cols[i].getDataType().isTimeStamp()) {
						Timestamp date = SQLUtil.getTimeStamp(inputs[inIdx++]);
						bo = new BindObject(date, cols[i].getDataType());
					} else if (cols[i].getDataType().isDate()) {
						Date date = SQLUtil.getDate(inputs[inIdx++]);
						bo = new BindObject(date, cols[i].getDataType());
					} else {
						bo = new BindObject(inputs[inIdx++],
								cols[i].getDataType());
					}
					request.addParameter(index, bo);
				}
				if (cols[i].isColumnOut() || cols[i].isColumnInOut()
						|| cols[i].isColumnReturn()) {
					request.addOutPutParameter(cols[i].getName(), index,
							cols[i].getDataType(), cols[i].getColumnType());
				}

			}
			CallResultAdaptor tr = new CallResultAdaptor(request);
			request.addListener(tr);

			SQLServerThread.putRequest(request);
			setEnabled(true);
		} else {
			System.out.println("error");
		}
	}

	// ------------------------------------------------------------
	// CLASS
	// ------------------------------------------------------------
	class CallResultAdaptor extends RequestAdaptor {
		CallRequest fTransactionRequest;

		public CallResultAdaptor(CallRequest req) {
			fTransactionRequest = req;
		}

		@Override
		public void called_done(Request request, SQLOperationType operation,
				ConnectionProperties properteis, Object o) {
			String[] ret = fTransactionRequest.getOutPutValues();
			final StringBuilder buf = new StringBuilder();

			buf.append(String.format("%n-----  INPUTS PARAMETERS -----%n"));
			Parameter[] inputs = fTransactionRequest.getInputParameters();
			for (int i = 0; i < inputs.length; i++) {
				buf.append(String.format("  [%02d] [%s]%n", (i + 1),
						inputs[i].value.toString()));
			}
			buf.append(String.format("%n----- OUTPUTS PARAMETERS -----%n"));
			for (int i = 0; i < ret.length; i++) {
				buf.append(String.format("  [%02d] [%s]%n", (i + 1), ret[i]));
			}
			display.asyncExec(new Runnable() {
				@Override
				public void run() {
					Dialog dialog = new SqlKeyHighlightDialog(shell, buf
							.toString());
					dialog.open();
				}
			});
		}
	}

	@Override
	public void selectionChanged(SelectionChangedEvent event) {
		// TODO Auto-generated method stub

	}
}