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

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

import gov.va.vinci.dart.dms.biz.Document;
import gov.va.vinci.dart.dms.biz.Label;
import gov.va.vinci.dart.dms.db.DocumentDAO;
import gov.va.vinci.dart.dms.db.LabelDAO;
import gov.va.vinci.dart.service.DartObjectFactory;

public class LabelDAOMock implements LabelDAO {

	private boolean initialized = false;
	private int idCounter = 1;
	private HashMap<Integer,Label> IDHash = new HashMap<Integer,Label>();
	
	@Override
	public void save(Label label) {
		if (label == null) {
			throw new IllegalArgumentException();
		}
		
		initializeLabelHash();
		
		if (label.getId() == 0) {
			label.setId(idCounter++);
		}
		
		// hibernate does this automatically
		if (label.getDocument() != null && label.getDocument().getLabels() != null && label.getDocument().getLabels().contains(label)) {
			label.getDocument().getLabels().add(label);
		}
		
		IDHash.put(label.getId(), label);
	}

	@Override
	public void delete(Label label) {
		if (label == null) {
			throw new IllegalArgumentException();
		}
		
		initializeLabelHash();

		// hibernate does this automatically
		for (Document doc : DartObjectFactory.getInstance().getDocumentDAO().listAll()) {
			if (doc.getLabels() != null && doc.getLabels().contains(label)) {
				doc.getLabels().remove(label);
			}
		}

		IDHash.remove(label.getId());
	}

	@Override
	public Label findById(int labelId) {
		initializeLabelHash();

		return IDHash.get(labelId);
	}

	@Override
	public void deleteAllCurrentLabels(int documentId) {

		DocumentDAO mock = DartObjectFactory.getInstance().getDocumentDAO();
		List<Document> dlist = mock.listVersionsById(documentId);
		
		List<Integer> removeList = new ArrayList<Integer>();
		
		// walk the list twice to avoid concurrent modification exceptions
		for (Integer id: IDHash.keySet()) {
			Label lbl = IDHash.get(id);
			if (dlist.contains(lbl.getDocument()) == true && Document.CURRENT_LABEL.equals(lbl.getValue())) {
				removeList.add(id);
			}
		}
		
		for (Integer id : removeList) {
			Label lbl = IDHash.get(id);
			IDHash.remove(id);
			
			// Hibernate does this automatically
			for (Document doc : mock.listAll()) {
				if (doc.getLabels() != null && doc.getLabels().contains(lbl) == true) {
					doc.getLabels().remove(lbl);
				}
			}
		}
	}

	public List<Label> listByDocumentId(int documentId) {
		List<Label> result = new ArrayList<Label>();

		for (Integer id: IDHash.keySet()) {
			Label lbl = IDHash.get(id);
			if (lbl.getDocument().getId() == documentId) {
				result.add(lbl);
			}
		}

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

}
