package info.bukova.isspst.services;

import org.hibernate.Query;

import java.util.Collection;

/**
 * @author Pepa Rokos
 */
public class HqlUtils {

	public static String buildHql(String select, HqlDataFilter filter) {
		if (select.toLowerCase().contains("where")
				|| select.toLowerCase().contains("order by")) {
			throw new IsspstException("Use add*() methods instead.");
		}

		String hql = addWhere(select, filter, "");
		return addOrderBy(hql, filter);
	}

	public static String addAndWhere(String hql, HqlDataFilter filter) {
		if (!checkWhere(filter)) {
			return hql;
		}

		return addWhere(hql, filter, "and");
	}

	public static String addOrWhere(String hql, HqlDataFilter filter) {
		if (!checkWhere(filter)) {
			return hql;
		}

		return addWhere(hql, filter, "or");
	}

	public static String addOrderBy(String hql, HqlDataFilter filter) {
		if (filter == null || filter.getOrderBy() == null || filter.getOrderBy().isEmpty()) {
			return  hql;
		}

		if (!hql.contains("order by")) {
			hql += " order by ";
		}

		hql += filter.getOrderBy();
		return hql;
	}

	public static void addParameters(Query query, HqlDataFilter filter) {
		if (filter == null) {
			return;
		}

		for (String key : filter.getParamKeys()) {
			if (filter.getParam(key) instanceof Collection<?>) {
				query.setParameterList(key, (Collection) filter.getParam(key));
			} else {
				query.setParameter(key, filter.getParam(key));
			}
		}
	}

	private static boolean checkWhere(HqlDataFilter filter) {
		return filter != null && filter.getWhere() != null && !filter.getWhere().isEmpty();
	}

	private static String addWhere(String hql, HqlDataFilter filter, String operator) {
		if (hql.toLowerCase().contains("where") && hql.toLowerCase().contains("order by")) {
			String[] split = hql.split("order by");
			hql = split[0] + " " + operator + " (" + filter.getWhere() + ") order by " + split[1];
			return hql;
		}

		if (hql.toLowerCase().contains("where")) {
			hql += " " + operator + " (" + filter.getWhere() + ")";
			return hql;
		}

		if (hql.toLowerCase().contains("order by")) {
			String[] split = hql.split("order by");
			hql = split[0] + " where (" + filter.getWhere() + ") order by " + split[1];
			return hql;
		}

		hql += " where (" + filter.getWhere() + ")";
		return hql;
	}
}
