/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.xtext.entitymock.common;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.osbp.dsl.common.datatypes.IDto;

public abstract class AEntityMockDataGenerator extends ABaseMockObject implements IEntityMockDataGenerator {

	@Override
	public int compareTo(IEntityMockDataGenerator o) {
		if	(getRunWithPriority() != o.getRunWithPriority()) {
			return (new Integer(getRunWithPriority())).compareTo((new Integer(o.getRunWithPriority())));
		}
		else {
			return getClass().getCanonicalName().compareTo(o.getClass().getCanonicalName());
		}
	}

	protected Map<MockedEntityDto,List<Object>> mockDataClassMap = new LinkedHashMap<>();
	protected Map<String,List<Object>> mockDataNamedMap = new LinkedHashMap<>();
	protected Map<IDto,Map<String,Object>> dtoMockDataMap = new LinkedHashMap<>();

	@Override
	public int getRunWithPriority() {
		return DEFAULT_PRIORITY;
	}
	
	protected void initialize() {
		mockDataClassMap.clear();
		mockDataNamedMap.clear();
		dtoMockDataMap.clear();
	}

	public void addDtoMockData(IDto dto, Map<String,Object> mockData) {
		dtoMockDataMap.put(dto, mockData);
	}
	
	public Object getDtoAttribute(IDto dto, String key) {
		Object value = null;
		Map<String,Object> mockData = dtoMockDataMap.get(dto);
		if	(mockData != null) {
			value = mockData.get(key);
		}
		return value;
	}
	
	protected final String getClassMapIndex(Class<?> forClass, String persistenceUnit) {
		return forClass.getCanonicalName()+"@"+persistenceUnit;
	}
	
	protected List<Object> getMockObjects(Class<?> forClass, String persistenceUnit) {
		for	(Entry<MockedEntityDto, List<Object>> entrySet : mockDataClassMap.entrySet()) {
			if	(entrySet.getKey().equals(forClass, persistenceUnit)) {
				return entrySet.getValue();
			}
		}
		return null;	// NOSONAR
	}
	
	protected List<Object> getMockObjects(String mockEntityName) {
		return mockDataNamedMap.get(mockEntityName);
	}
	
	protected void addMockObjects(String mockEntityName, List<Object> objects) {
		mockDataNamedMap.put(mockEntityName, objects);
	}
	
	protected void addMockObjects(String mockEntityName, Class<?> forClass, String persistenceUnit, List<Object> addList) {
		List<Object> targetList;
		targetList = getMockObjects(forClass, persistenceUnit);
		if	(targetList==null) {
			targetList = new ArrayList<>(addList);
			mockDataClassMap.put(new MockedEntityDto(forClass, persistenceUnit), targetList);
		}
		else {
			targetList.addAll(addList);
		}
		targetList = getMockObjects(mockEntityName);
		if	(targetList==null) {
			targetList = new ArrayList<>(addList);
			mockDataNamedMap.put(mockEntityName, targetList);
		}
		else {
			targetList.addAll(addList);
		}
	}
	
	@Deprecated
	protected final void generateDataRow() {
	}

}
