/**
 *                                                                            
 * 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 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.xtext.entitymock.common;

import java.util.ArrayList;
import java.util.Base64;
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 static byte[] asByteArray(Object value) {
		// store the text in base64 encode to be compatible with the referenced blob handler.
		return (value == null) ? null : Base64.getEncoder().encode(value.toString().getBytes());
	}
	
	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) {
			if( mockObjects.length>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 {
			if( mockObjects.length>0 )
				getMockData().put(key, mockObjects[getFillerProvider().unsignedinteger(mockObjects.length-1)]);
		}
	}
}
