package gov.va.vinci.dart.db.mock;

import java.util.ArrayList;
import java.util.List;

import gov.va.vinci.dart.biz.GroupTask;
import gov.va.vinci.dart.biz.PersonTask;
import gov.va.vinci.dart.biz.Task;
import gov.va.vinci.dart.db.TaskDAO;
import gov.va.vinci.dart.service.DartObjectFactory;

public class TaskDAOMock implements TaskDAO {

	private static boolean initialized = false;
	private static int idCounter = 1;
	
	// allocate an id for the task but leave it to PersonTaskDAO and GroupTaskDAO to save the object in their hashes.
	@Override
	public synchronized void save(final Task task) {
		if (task == null) {
			throw new IllegalArgumentException();
		}

		initializeTaskHash();

		if (task.getId() == 0) {
			task.setId(idCounter++);
		}
	}
	
	
	@Override
	public void delete(final Task task) {
		if (task == null) {
			throw new IllegalArgumentException();
		}

		initializeTaskHash();

		if( GroupTask.class.isAssignableFrom(task.getClass()) ) {
			
			DartObjectFactory.getInstance().getGroupTaskDAO().delete( (GroupTask)task );
			
		} else if( PersonTask.class.isAssignableFrom(task.getClass()) ) {
			
			DartObjectFactory.getInstance().getPersonTaskDAO().delete( (PersonTask)task );
			
		}
	}
	
	
	@Override
	public Task findById(int taskId) {
		initializeTaskHash();
		
		Task result = DartObjectFactory.getInstance().getPersonTaskDAO().findById(taskId);
		if (result == null) {
			result = DartObjectFactory.getInstance().getGroupTaskDAO().findById(taskId);
		}
		
		return result;
	}

	@Override
	public List<Task> listByRequestId(int requestId) {
		List<Task> result = new ArrayList<Task>();
		
		initializeTaskHash();

		for (PersonTask pt : DartObjectFactory.getInstance().getPersonTaskDAO().listAllPersonTasks()) {
			if (pt != null && requestId == pt.getRequest().getId()) {
				result.add(pt);
			}
		}

		for (GroupTask pt : DartObjectFactory.getInstance().getGroupTaskDAO().listAllGroupTasks()) {
			if (pt != null && requestId == pt.getRequest().getId()) {
				if (result.contains(pt) == false) {
					result.add(pt);
				}
			}
		}

		return result;	
	}

	@Override
	public List<Task> listOpenByRequestId(int requestId) {
		List<Task> result = new ArrayList<Task>();
		
		initializeTaskHash();

		for (PersonTask pt : DartObjectFactory.getInstance().getPersonTaskDAO().listAllPersonTasks()) {
			if (pt != null && requestId == pt.getRequest().getId() && pt.getCompletedOn() == null) {
				result.add(pt);
			}
		}

		for (GroupTask pt : DartObjectFactory.getInstance().getGroupTaskDAO().listAllGroupTasks()) {
			if (pt != null && requestId == pt.getRequest().getId() && pt.getCompletedOn() == null) {
				if (result.contains(pt) == false) {
					result.add(pt);
				}
			}
		}

		return result;	
	}

	
	@Override
	public List<Task> listOpenByWorkflowAndRequestId(final int workflowId, final int requestId) {	
		List<Task> result = new ArrayList<Task>();
		
		initializeTaskHash();

		for (PersonTask pt : DartObjectFactory.getInstance().getPersonTaskDAO().listAllPersonTasks()) {
			if (pt != null && requestId == pt.getRequest().getId() && pt.getCompletedOn() == null) {

				if( pt.getWorkflow() != null && pt.getWorkflow().getId() == workflowId ) {	//get the tasks for this workflow
					result.add(pt);
				}

			}
		}

		for (GroupTask gt : DartObjectFactory.getInstance().getGroupTaskDAO().listAllGroupTasks()) {
			if (gt != null && requestId == gt.getRequest().getId() && gt.getCompletedOn() == null) {

				if( gt.getWorkflow() != null && gt.getWorkflow().getId() == workflowId ) {	//get the tasks for this workflow
					if (result.contains(gt) == false) {
						result.add(gt);
					}
				}

			}
		}

		return result;	
	}

	
	@Override
	public List<Task> listAll() {
		List<Task> result = new ArrayList<Task>();
		
		initializeTaskHash();

		result.addAll(DartObjectFactory.getInstance().getPersonTaskDAO().listAllPersonTasks());
		
		for (GroupTask pt : DartObjectFactory.getInstance().getGroupTaskDAO().listAllGroupTasks()) {
			if (pt != null) {
				if (result.contains(pt) == false) {
					result.add(pt);
				}
			}
		}

		return result;	
	}

	private void initializeTaskHash() {
		if (initialized == true) {
			return;
		}
		
		initialized = true;
	}
	
}
