/*******************************************************************************
 * Copyright (c) 2009, 2018 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.benchmark.preparation.notifications;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.impl.EEnumImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMLResource;

public class RawNotification {
    	public final static String LINK_ADD_EVENT = "LinkAddEvent";
    	public final static String LINK_REMOVE_EVENT = "LinkRemoveEvent";
    	public final static String ATTRIBUTE_VALUE_CHANGE_EVENT = "AttributeValueChangeEvent";
    	public final static String ELEMENT_DELETE_EVENT = "ElementDeleteEvent";
    	public final static String ELEMENT_CREATE_EVENT ="ElementCreateEvent";

	private final String eventType;
	private final Map<String, String> attributeMap;

	private int splitNumber = -1;

	public RawNotification(String eventType, Map<String, String> attributeMap){
	    this.eventType = eventType;
	    this.attributeMap = attributeMap;
	    // TODO Auto-generated constructor stub
	}

	public String getEventType() {
	    return eventType;
	}

	public Map<String, String> getAttributeMap() {
	    return attributeMap;
	}


	public boolean isSplitCandidate(){
	    return getEventType().equals(LINK_ADD_EVENT) || getEventType().equals(LINK_REMOVE_EVENT);
	}

	public boolean wasSplitted(){
	    return isSplitCandidate() && splitNumber >= 0;
	}

	public int getSplitNumber(){
	    assert wasSplitted();

	    return splitNumber;
	}

	private void setSplitNumber(int i){
	    assert isSplitCandidate();

	    splitNumber = i;
	}

	public ArrayList<RawNotification> split(){
	    if(!isSplitCandidate()) {
		throw new RuntimeException("This notification cannot be splitted");
	    }

	    ArrayList<RawNotification> result = new ArrayList<RawNotification>();

	    if(getEventType().equals(LINK_ADD_EVENT) || getEventType().equals(LINK_REMOVE_EVENT)){
    		for(int i = 0; i < 2; i++){
    		RawNotification noti = new RawNotification(getEventType(), getAttributeMap());
    		noti.setSplitNumber(i);
    		result.add(noti);
		}
	    }

	    return result;
	}


    public Notification convertToNotification(Resource resource){
            // FIXME: Conversion only works for AttributeValueChanges at the moment. Add support for all event types
            // FIXME: By adding support for more events the following if condition must be refactored
            if (getEventType().equals(ATTRIBUTE_VALUE_CHANGE_EVENT)) {
        	//System.out.println("AttributeValueChangeEvent");

        	String mofId = getAttributeMap().get("MRI").split("#")[1];
        	EObject obj = resource.getEObject(mofId);

        	EAttribute attribute = null;
        	if (obj != null) {

        	    for (EObject contentObject : obj.eClass().getEAllAttributes()) {
                	    if (contentObject instanceof EAttribute) {
                		if (((EAttribute) contentObject).getName().equals(getAttributeMap().get("attribute"))) {
                		    attribute = (EAttribute) contentObject;
                		}
                	    }
        	    }

        	    if(attribute != null){
        		String oldValue = getAttributeMap().get("oldValue");
        		String newValue = getAttributeMap().get("newValue");

        		Object oldValueParsed = null;
        		Object newValueParsed = null;


		    if (oldValue.equalsIgnoreCase("true") || oldValue.equalsIgnoreCase("false")) {
			oldValueParsed = Boolean.parseBoolean(oldValue);
			newValueParsed = Boolean.parseBoolean(newValue);
		    }

		    if (oldValueParsed == null || newValueParsed == null) {
			try {
			    oldValueParsed = Integer.parseInt(oldValue);
			    newValueParsed = Integer.parseInt(newValue);
			} catch (NumberFormatException e) {

			}
		    }

		    if (oldValueParsed == null || newValueParsed == null) {
			oldValueParsed = oldValue;
			newValueParsed = newValue;
		    }

		    if(attribute.getEAttributeType() instanceof EEnumImpl){
			EEnumImpl enumType = (EEnumImpl)attribute.getEAttributeType();
			Class<?> enumClass = enumType.getInstanceClass();
			for(Object constant : enumClass.getEnumConstants()){
			    if(constant.toString().equals(oldValue)){
				oldValueParsed = constant;
			    }
			    if(constant.toString().equals(newValue)){
				newValueParsed = constant;
			    }
			}

			if(oldValue.equals("null")){
			    oldValueParsed = null;
			}
			if(newValue.equals("null")){
			    newValueParsed = null;
			}
		    }

			return NotificationHelper.createAttributeChangeNotification(obj, attribute, oldValueParsed, newValueParsed);
        	    }
        	}else{
        	    //System.out.println("Element with MOFID: " + mofId + " cannot be found in Resource");
        	}
            }else if(getEventType().equals(LINK_REMOVE_EVENT)){
        	//System.out.println("LinkRemoveEvent");

        	String mofId1 = getAttributeMap().get("MRI1").split("#")[1];
        	EObject obj1 = resource.getEObject(mofId1);

        	String mofId2 = getAttributeMap().get("MRI2").split("#")[1];
        	EObject obj2 = resource.getEObject(mofId2);

        	if(obj1 != null && obj2 != null){
        	//	System.out.println("Both not null");

        	    if(wasSplitted() && getSplitNumber() == 0) {
			//   	System.out.println("Split" + 0);
        	    	return createLinkRemoveNotification(obj1, obj2);
		    } else if(wasSplitted() && getSplitNumber() == 1) {
			//	   System.out.println("Split" + 1);
			   return createLinkRemoveNotification(obj2, obj1);
		    } else {
			return null;
		    }
        	}
            }else if(getEventType().equals(LINK_ADD_EVENT)){
        	//System.out.println("LinkAddEvent");

        	String mofId1 = getAttributeMap().get("MRI1").split("#")[1];
        	EObject obj1 = resource.getEObject(mofId1);

        	String mofId2 = getAttributeMap().get("MRI2").split("#")[1];
        	EObject obj2 = resource.getEObject(mofId2);

        	String rolename1 = getAttributeMap().get("AE2");
        	String rolename2 = getAttributeMap().get("AE3");

        	if(obj1 != null && obj2 != null){
        	//	System.out.println("Both not null");

        	    if(wasSplitted() && getSplitNumber() == 0) {
			//   	System.out.println("Split" + 0);
        	    	return createLinkAddNotification(obj1, obj2, rolename1, rolename2);
		    } else if(wasSplitted() && getSplitNumber() == 1) {
			//   	System.out.println("Split" + 1);
        	    	return createLinkAddNotification(obj2, obj1, rolename2, rolename1);
		    } else {
			return null;
		    }
        	}
            }else if(getEventType().equals(ELEMENT_DELETE_EVENT)){
        	//System.out.println("ElementDeleteEvent");
        	String mofId = getAttributeMap().get("MRI").split("#")[1];
        	EObject obj = resource.getEObject(mofId);

        	if (obj != null) {
		    return NotificationHelper.createElementDeleteNotification(obj);
		}
            }else if(getEventType().equals(ELEMENT_CREATE_EVENT)){
        	//System.out.println("ElementCreateEvent");

        	//FIXME: Change
        	    ClassLoader classLoader = RealWorldReplayNotificationProducer.class.getClassLoader();

        	    try {
        		String type = getAttributeMap().get("type");

        	   	String[] splittedType = type.split("\\.");

        		String clazz = splittedType[splittedType.length - 1];

        		String packagePath = type.split(clazz)[0];

        		String fullPackagePath = packagePath.toLowerCase() + splittedType[splittedType.length - 2].substring(0,1).toUpperCase() + splittedType[splittedType.length - 2].substring(1).toLowerCase() + "Package";

        	        Class<?> aClass = classLoader.loadClass(fullPackagePath);
        	        Field instance = aClass.getField("eINSTANCE");
        	        EPackage pack= (EPackage)instance.get(null);

        	        Method thisMethod = pack.getClass().getDeclaredMethod("get" + clazz);
        	        // call the method
        	        EClass classToCreate = (EClass)thisMethod.invoke(pack);

        	        EObject obj = pack.getEFactoryInstance().create(classToCreate);


        	        	Notification res = NotificationHelper.createNewElementAddToResourceNotification(obj, resource);
             	    	((XMLResource)resource).setID(obj, getAttributeMap().get("MRI").split("#")[1]);
             	    	return res;


        	    } catch (ClassNotFoundException e) {
        	           e.printStackTrace();
        	    } catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    }
            }


        return null;
    }

    private Notification createLinkRemoveNotification(EObject obj1, EObject obj2) {
	for(EReference reference : obj1.eClass().getEAllReferences()){
	if(obj1.eGet(reference) != null){
	    if(obj1.eGet(reference) instanceof EList<?>){
	        @SuppressWarnings("unchecked")
	            EList<EObject> eObjectList = (EList<EObject>)obj1.eGet(reference);
		for(EObject referencedObj : eObjectList){
		    if(referencedObj.equals(obj2)) {
			return NotificationHelper.createReferenceRemoveNotification(obj1, reference, obj2);
		    }
		}
	    }else if(obj1.eGet(reference).equals(obj2)) {
		return NotificationHelper.createReferenceRemoveNotification(obj1, reference, obj2);
	    }
	}
	}

	return null;
    }

    private Notification createLinkAddNotification(EObject obj1, EObject obj2, String rolename1, String rolename2) {
    	Notification result = null;
	for(EReference reference : obj1.eClass().getEAllReferences()){
		if(reference.getEType().isInstance(obj2)){
			//System.out.println("Match1");
			if(reference.getName().equals(rolename1) || reference.getName().equals(rolename2)){
				//System.out.println("Match2");
				result = NotificationHelper.createReferenceAddNotification(obj1, reference, obj2);
			}
		}
	}

	return result;
    }
}
