/**
 *                                                                            
 * 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.Collection;
import java.util.Date;
import java.util.List;

import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.jpa.services.Query;
import org.eclipse.osbp.runtime.common.filter.IDTOService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class ABaseMockEntity<E> extends ABaseMockObject {
	
	private static final Logger log = LoggerFactory.getLogger(ABaseMockEntity.class);

	protected static boolean asBoolean(Object value) {
		if(value == null) {
			return false;
		}
		if(value instanceof Boolean) {
			return (Boolean)value;
		} 
		if(value instanceof String) {
			return Boolean.parseBoolean(value.toString());
		}
		return false;
	}
	
	protected static Date asDate(Object value) {
		return (value instanceof Date) ? (Date)value : null;
	}
	
	protected static double asDouble(Object value) {
		if	(value instanceof Double) {
			return (Double)value;
		}
		else if (value instanceof Float) {
			return (Float)value;
		}
		else if (value == null) {
			return 0.0;
		}
		return Double.parseDouble(value.toString());
	}
	
	protected static float asFloat(Object value) {
		if	(value instanceof Float) {
			return (Float)value;
		}
		else if (value == null) {
			return (float)0.0;
		}
		return Float.parseFloat(value.toString());
	}
	
	protected static long asLong(Object value) {
		if	(value instanceof Long) {
			return (Long)value;
		}
		else if	(value instanceof Integer) {
			return (Integer)value;
		}
		else if	(value instanceof Short) {
			return (Short)value;
		}
		else if (value == null) {
			return 0;
		}
		return Long.parseLong(value.toString());
	}
	
	protected static int asInt(Object value) {
		if	(value instanceof Integer) {
			return (Integer)value;
		}
		else if	(value instanceof Short) {
			return (Short)value;
		}
		else if (value == null) {
			return 0;
		}
		return Integer.parseInt(value.toString());
	}
	
	protected static short asShort(Object value) {
		if	(value instanceof Short) {
			return (Short)value;
		}
		else if (value == null) {
			return 0;
		}
		return Short.parseShort(value.toString());
	}
	
	protected static String asString(Object value) {
		return (value == null) ? null : value.toString();
	}
	
	protected final AEntityMockDataGenerator mockDataGenerator;
	protected final String persistenceUnit;
	
	protected E entity;
	
	public ABaseMockEntity(AEntityMockDataGenerator mockDataGenerator, String persistenceUnit) {
		this.mockDataGenerator = mockDataGenerator;
		this.persistenceUnit = persistenceUnit;
	}
	
	public final String getPersistenceUnit() {
		return persistenceUnit;
	}
	
	public abstract E generateEntity(Object iteratorItem);
	
	protected final void generateAttribute(String key, Class<IDto> dtoClass, double optionalFor) {
		String mockEntityName = "Existing"+dtoClass.getSimpleName();
		if	(mockDataGenerator.getMockObjects(mockEntityName) == null) {
			List<Object> existingDtos = new ArrayList<>();
			try {
				IDTOService<?> dtoService = DtoServiceAccess.getService(dtoClass);
				if (dtoService == null) {
					log.error("NO DTO SERVICE FOUND for {} in persistence {}", dtoClass.getCanonicalName(), persistenceUnit);
				}
				else {
					Query queryAll = new Query();
					Collection<?> dtoObjects = dtoService.find(queryAll);
					for (Object dtoObject : dtoObjects) {
						existingDtos.add(dtoObject);
					}
				}
			}
			catch (Exception e) {
				log.error("could not retrieve existing entities via dto service for "+dtoClass.getCanonicalName(), e);
			}
			mockDataGenerator.addMockObjects(mockEntityName, existingDtos);
		}
		generateAttribute(key, mockEntityName, optionalFor);
	}
	
	protected final void generateAttribute(String key, String mockEntityName, double optionalFor) {
		Object[] mockObjects = null;
		if	(mockDataGenerator.getMockObjects(mockEntityName) != null) {
			mockObjects = mockDataGenerator.getMockObjects(mockEntityName).toArray();
		}
		// --- no objects are available ---
		if	(mockObjects == null) {
		    getMockData().put(key, null);
		}
		// --- if at least 100% have to be optional, EVERYTHING is optional ---
		else if	(optionalFor >= 1.0) {
		    getMockData().put(key, null);                                
		}
		// --- if up to 0% have to be optional, EVERYTHING is mandatory ---
		else if (optionalFor <= 0.0) {
		    getMockData().put(key, mockObjects[getFillerProvider().unsignedinteger(mockObjects.length-1)]);                                
		}
		// --- if a random is lower than the given optionalFor, this item is optional ---
		else if (getFillerProvider().unsigneddouble(0) < optionalFor*100.0) {
		    getMockData().put(key, null);                                
		}
		// --- otherwise
		else {
			getMockData().put(key, mockObjects[getFillerProvider().unsignedinteger(mockObjects.length-1)]);
		}
	}
}
