// Path: src/main/java/in/cubestack/android/lib/storm/FieldType.java
// public enum FieldType {
// 
//     INTEGER ,
//     TEXT ,
//     REAL,
//     OBJECT, LONG, DOUBLE ;
// 
//     public String getEscapeString() {
//         return "''";
//     }
// 
//     public static final String STD_DATE_FORMAT = "yyyy/MM/dd";
// 
// }
// 
// Path: src/main/java/in/cubestack/android/lib/storm/lifecycle/LifeCycleHandler.java
// public interface LifeCycleHandler<E> {
// 
// 	//Will always be Sync as there is a decision to make
// 	public boolean preSave(E entity);
// 	//Can be called Async
// 	public void postSave(E entity, Throwable throwable);
// 	
// 	//Will always be Sync as there is a decision to make
// 	public boolean preDelete(E entity);
// 	//Can be Async
// 	public void postDelete(E entity, Throwable throwable);
// }
// 
// Path: src/main/java/in/cubestack/android/lib/storm/util/Reflections.java
// public class Reflections {
//     public static void setField(Object object, String fieldName, Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//         try {
//             Field field = doGetIt(fieldName, object.getClass());
//             field.setAccessible(true);
//             
//             field.set(object, value);
//             field.setAccessible(false);
//         } catch (Exception ex) {
//             Log.e("ERRORR", "Error while setting " + fieldName + "of " + object.getClass() + " with value " + value, ex);
//         }
//     }
//     
//     public static Object getFieldStatic(Class<?> object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//             Field field = doGetIt(fieldName, object);
//             
//             field.setAccessible(true);
//             Object returnValue = (Object) field.get(null);
//             field.setAccessible(false);
//             
//             return returnValue;
//     }
//     
//     public static boolean isValidField(Class<?> targetClass, String fieldName)  throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//     	Field field = doGetIt(fieldName, targetClass);
//     	if(field == null) {
//     		return false;
//     	}
//     	return true;
//     }
// 
//     public static Object getFieldValue(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//         Field field = doGetIt(fieldName, object.getClass());
// 
//         field.setAccessible(true);
//         Object returnValue = (Object) field.get(object);
//         field.setAccessible(false);
//         return returnValue;
//     }
// 
// 
// 
//     private static Field doGetIt(String name, Class<?> clazz) {
//         Class<?> superClz = clazz;
//         while (superClz.getSuperclass() != null) {
//             for (Field field : superClz.getDeclaredFields()) {
//                 if (field.getName().equals(name)) {
//                     return field;
//                 }
//             }
//             superClz = superClz.getSuperclass();
//         }
//         return null;
//     }
// }


import java.lang.reflect.Field;
import in.cubestack.android.lib.storm.FieldType;
import in.cubestack.android.lib.storm.annotation.Column;
import in.cubestack.android.lib.storm.annotation.Database;
import in.cubestack.android.lib.storm.annotation.LifeCycle;
import in.cubestack.android.lib.storm.annotation.PrimaryKey;
import in.cubestack.android.lib.storm.annotation.Relation;
import in.cubestack.android.lib.storm.annotation.Table;
import in.cubestack.android.lib.storm.lifecycle.LifeCycleHandler;
import in.cubestack.android.lib.storm.util.Reflections;

		} catch (Exception exception) {
			throw new StormException(String.format("Please check the mapping for @Relation for class %s, mapped for parent class %s", relationMetaData.getTargetEntity(), 
					tableInfo.getMappedClass()), exception);
		}

	}

	private void generateCreate() throws IllegalArgumentException, IllegalAccessException, InstantiationException {
		tableInformation.setInsertSql(queryGenerator.insertQuery(tableInformation, tableInformation.isAutoGenerated()));
	}

	public DatabaseMetaData fetchDatabaseMetaData(Class<?> databaseClass) {
		Database database = databaseClass.getAnnotation(Database.class);
		DatabaseMetaData metaData = new DatabaseMetaData();
		metaData.setVersion(database.version());
		metaData.setName(database.name());
		metaData.setTables(database.tables());
		metaData.setHandler(database.handler());
		return metaData;
	}

	private ColumnMetaData getColumnMetaData(Field field) throws IllegalArgumentException, IllegalAccessException {
		ColumnMetaData columnMetaData = new ColumnMetaData();
		Column column = field.getAnnotation(Column.class);
		String alias = field.getName();
		String columnName = column.name();
		boolean parentReferenceKey = column.parentReferenceKey();
		columnMetaData.setParentReferenceKey(parentReferenceKey);
		columnMetaData.setAlias(alias);
		columnMetaData.setColumnName(columnName);

// Path: src/main/java/in/cubestack/android/lib/storm/FieldType.java
// public enum FieldType {
// 
//     INTEGER ,
//     TEXT ,
//     REAL,
//     OBJECT, LONG, DOUBLE ;
// 
//     public String getEscapeString() {
//         return "''";
//     }
// 
//     public static final String STD_DATE_FORMAT = "yyyy/MM/dd";
// 
// }
// 
// Path: src/main/java/in/cubestack/android/lib/storm/lifecycle/LifeCycleHandler.java
// public interface LifeCycleHandler<E> {
// 
// 	//Will always be Sync as there is a decision to make
// 	public boolean preSave(E entity);
// 	//Can be called Async
// 	public void postSave(E entity, Throwable throwable);
// 	
// 	//Will always be Sync as there is a decision to make
// 	public boolean preDelete(E entity);
// 	//Can be Async
// 	public void postDelete(E entity, Throwable throwable);
// }
// 
// Path: src/main/java/in/cubestack/android/lib/storm/util/Reflections.java
// public class Reflections {
//     public static void setField(Object object, String fieldName, Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//         try {
//             Field field = doGetIt(fieldName, object.getClass());
//             field.setAccessible(true);
//             
//             field.set(object, value);
//             field.setAccessible(false);
//         } catch (Exception ex) {
//             Log.e("ERRORR", "Error while setting " + fieldName + "of " + object.getClass() + " with value " + value, ex);
//         }
//     }
//     
//     public static Object getFieldStatic(Class<?> object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//             Field field = doGetIt(fieldName, object);
//             
//             field.setAccessible(true);
//             Object returnValue = (Object) field.get(null);
//             field.setAccessible(false);
//             
//             return returnValue;
//     }
//     
//     public static boolean isValidField(Class<?> targetClass, String fieldName)  throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//     	Field field = doGetIt(fieldName, targetClass);
//     	if(field == null) {
//     		return false;
//     	}
//     	return true;
//     }
// 
//     public static Object getFieldValue(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
//         Field field = doGetIt(fieldName, object.getClass());
// 
//         field.setAccessible(true);
//         Object returnValue = (Object) field.get(object);
//         field.setAccessible(false);
//         return returnValue;
//     }
// 
// 
// 
//     private static Field doGetIt(String name, Class<?> clazz) {
//         Class<?> superClz = clazz;
//         while (superClz.getSuperclass() != null) {
//             for (Field field : superClz.getDeclaredFields()) {
//                 if (field.getName().equals(name)) {
//                     return field;
//                 }
//             }
//             superClz = superClz.getSuperclass();
//         }
//         return null;
//     }
// }


// Path: src/main/java/in/cubestack/android/lib/storm/core/MetaDataReader.java
import java.lang.reflect.Field;
import in.cubestack.android.lib.storm.FieldType;
import in.cubestack.android.lib.storm.annotation.Column;
import in.cubestack.android.lib.storm.annotation.Database;
import in.cubestack.android.lib.storm.annotation.LifeCycle;
import in.cubestack.android.lib.storm.annotation.PrimaryKey;
import in.cubestack.android.lib.storm.annotation.Relation;
import in.cubestack.android.lib.storm.annotation.Table;
import in.cubestack.android.lib.storm.lifecycle.LifeCycleHandler;
import in.cubestack.android.lib.storm.util.Reflections;

		} catch (Exception exception) {
			throw new StormException(String.format("Please check the mapping for @Relation for class %s, mapped for parent class %s", relationMetaData.getTargetEntity(), 
					tableInfo.getMappedClass()), exception);
		}

	}

	private void generateCreate() throws IllegalArgumentException, IllegalAccessException, InstantiationException {
		tableInformation.setInsertSql(queryGenerator.insertQuery(tableInformation, tableInformation.isAutoGenerated()));
	}

	public DatabaseMetaData fetchDatabaseMetaData(Class<?> databaseClass) {
		Database database = databaseClass.getAnnotation(Database.class);
		DatabaseMetaData metaData = new DatabaseMetaData();
		metaData.setVersion(database.version());
		metaData.setName(database.name());
		metaData.setTables(database.tables());
		metaData.setHandler(database.handler());
		return metaData;
	}

	private ColumnMetaData getColumnMetaData(Field field) throws IllegalArgumentException, IllegalAccessException {
		ColumnMetaData columnMetaData = new ColumnMetaData();
		Column column = field.getAnnotation(Column.class);
		String alias = field.getName();
		String columnName = column.name();
		boolean parentReferenceKey = column.parentReferenceKey();
		columnMetaData.setParentReferenceKey(parentReferenceKey);
		columnMetaData.setAlias(alias);
		columnMetaData.setColumnName(columnName);

		FieldType fieldType = column.type();
