package hiro.yoshioka.sql.util;

import hiro.yoshioka.ast.sql.IToken;
import hiro.yoshioka.ast.sql.util.BindInfo;
import hiro.yoshioka.sql.resource.IDBTable;
import hiro.yoshioka.util.LinesString;
import hiro.yoshioka.util.StringUtil;

import java.util.ArrayList;

public class OracleBlobInfo {

	String originalSql;
	String changedSql;
	boolean markSpecialBlobExecution;
	BindInfo[] blobedInfos;

	public boolean isMarkSpecialBlobExecution() {
		return markSpecialBlobExecution;
	}

	public BindInfo[] getBlobedInfos() {
		return blobedInfos;
	}

	public String getChangedSql() {
		return changedSql;
	}

	public OracleBlobInfo(IDBTable table, String sqlStatement, BindInfo[] binds) {
		this.originalSql = sqlStatement;
		this.changedSql = sqlStatement;

		StringBuilder returning = new StringBuilder();
		ArrayList<BindInfo> infoList = new ArrayList<BindInfo>();
		for (int i = binds.length - 1; i >= 0; i--) {
			if (binds[i].isBlob()
					&& !StringUtil.isEmpty(binds[i].getStringValue())
					&& !StringUtil.isEmpty(binds[i].getTarget())) {
				LinesString lines = new LinesString(changedSql);
				boolean find = false;
				StringBuffer buf = new StringBuffer();
				IToken questionToken = binds[i].getQuestionToken();
				if (questionToken != null) {
					int offset = lines.getOffsetByRowColNumber(
							questionToken.getBeginLine(),
							questionToken.getBeginColumn());
					buf.append(changedSql.substring(0, offset));
					buf.append("EMPTY_BLOB()");
					buf.append(changedSql.substring(offset + 1));

					markSpecialBlobExecution = true;
					infoList.add(binds[i]);
					if (returning.length() == 0) {
						returning.append(" returning ");
					} else {
						returning.append(", ");
					}
					returning.append(binds[i].getTarget()).append(" into ?");

					changedSql = buf.toString();
				}
			}
		}

		blobedInfos = infoList.toArray(new BindInfo[infoList.size()]);
		changedSql = "begin " + StringUtil.LINE_SEPARATOR + changedSql
				+ StringUtil.LINE_SEPARATOR;
		changedSql += returning + ";" + StringUtil.LINE_SEPARATOR;
		changedSql += "end;";

		changedSql = changedSql.replaceAll("[\r　\t]+", " ");
	}
}
