package de.thomasjacob.improve.logic.issue;

import de.thomasjacob.webcore.TechnicalException;
import de.thomasjacob.webcore.logic.Dao;

import java.util.List;
import java.util.StringTokenizer;

import net.sf.hibernate.HibernateException;


public class IssueDao extends Dao
{

	public static final int ORDER_BY_REPORTER = 7;

	public static final int ORDER_BY_DEVELOPER = 8;

	public static final int ORDER_BY_ID = 1;

	public static final int ORDER_BY_NAME = 2;

	public static final int ORDER_BY_PRIORITY = 5;

	public static final int ORDER_BY_PROJECT = 3;

	public static final int ORDER_BY_STATUS = 6;

	public static final int ORDER_BY_TYPE = 4;

	public List findIssues(String projectId, String type, String maximumPriority, String status, String reporterId,
		String developerId, String issueId, String searchString, int order) throws TechnicalException
	{
		StringBuffer query = new StringBuffer("from Issue issue");
		query.append(" where priority <= ").append(maximumPriority.equals("") ? 5 : Integer.parseInt(maximumPriority));

		if (!projectId.equals(""))
		{
			query.append(" and issue.project.id = ").append(projectId);
		}

		if (!type.equals(""))
		{
			query.append(" and issue.type = ").append(type);
		}

		if (!status.equals(""))
		{
			query.append(" and issue.status = ").append(status);
		}

		if (!reporterId.equals(""))
		{
			query.append(" and issue.reporter.id = ").append(reporterId);
		}

		if (!developerId.equals(""))
		{
			if (developerId.equals("0"))
			{
				query.append(" and issue.developer = null");
			}
			else
			{
				query.append(" and issue.developer.id = " + developerId);
			}
		}

		if (!issueId.equals(""))
		{
			query.append(" and issue.id = ").append(issueId);
		}

		if (!searchString.equals(""))
		{
			String nameConditions = null;
			String descriptionConditions = null;

			StringTokenizer tokenizer = new StringTokenizer(searchString, " ");
			while (tokenizer.hasMoreTokens())
			{
				String token = tokenizer.nextToken().trim();
				if (token.length() > 0)
				{
					if (nameConditions != null)
					{
						nameConditions = nameConditions + " and ";
						descriptionConditions = descriptionConditions + " and ";
					}

					nameConditions = "issue.name like '%" + token + "%'";
					descriptionConditions = "issue.description like '%" + token + "%'";
				}
			}

			if (nameConditions != null)
			{
				query.append(" and (" + nameConditions + " or " + descriptionConditions + ")");
			}
		}

		String orderColumn;
		switch (order)
		{
			case ORDER_BY_ID:
				orderColumn = "issue.id";
			break;

			case ORDER_BY_NAME:
				orderColumn = "issue.name";
			break;

			case ORDER_BY_PROJECT:
				orderColumn = "issue.project.name";
			break;

			case ORDER_BY_TYPE:
				orderColumn = "issue.type";
			break;

			case ORDER_BY_PRIORITY:
				orderColumn = "issue.priority";
			break;

			case ORDER_BY_STATUS:
				orderColumn = "issue.status";
			break;

			case ORDER_BY_REPORTER:
				orderColumn = "issue.reporter.name";
			break;

			case ORDER_BY_DEVELOPER:
				orderColumn = "issue.developer.name";
			break;

			default:
				throw new IllegalArgumentException("Unknown order column");
		}

		query.append(" order by " + orderColumn);

		try
		{
			return getSession(false).find(query.toString());
		}
		catch (HibernateException exception)
		{
			throw new TechnicalException("hibernate operation failed", exception);
		}
	}

	public Issue getIssueById(int issueId) throws TechnicalException
	{
		return (Issue) getModelById(Issue.class, issueId);
	}
}
