//------------------------------------------------------------------------------
// Copyright (c) 2005, 2012 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.meta;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.common.utils.ExtensionHelper;
import org.eclipse.epf.library.edit.meta.internal.ModifiedTypeMetaImpl;
import org.eclipse.epf.library.edit.meta.internal.TypeDefParserImpl;
import org.eclipse.epf.library.edit.uma.DescriptorExt;
import org.eclipse.epf.library.edit.uma.MethodElementExt;
import org.eclipse.epf.library.edit.uma.MethodElementExt.WorkProductStateExt;
import org.eclipse.epf.library.edit.uma.MethodPluginExt;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.PracticePropUtil;
import org.eclipse.epf.library.edit.util.PropUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Constraint;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.util.ExtendedAttribute;
import org.eclipse.epf.uma.util.ExtendedReference;
import org.eclipse.epf.uma.util.MetaElement;
import org.eclipse.epf.uma.util.ModifiedTypeMeta;
import org.eclipse.epf.uma.util.QualifiedReference;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.epf.uma.util.UserDefinedTypeMeta;

/**
 * @author Weiping Lu
 */
public class TypeDefUtil {

	private static TypeDefUtil instance;
	
	static {
		Object obj = ExtensionHelper.create(TypeDefUtil.class, null);
		if (obj instanceof TypeDefUtil) {
			instance = (TypeDefUtil) obj;
		} else {
			instance = new TypeDefUtil();
		}
	}
	
	public static TypeDefUtil getInstance() {
		return instance;
	}

	protected TypeDefUtil() {		
	}
	
	public TypeDefParser getTypeDefParser() {
		return new TypeDefParserImpl();
	}
	
	public IMetaDef createMetaDef(Class cls) {
		if (cls == ModifiedTypeMeta.class) {
			return (ModifiedTypeMetaImpl) newModifiedTypeMeta();
		}
		return null;
	}
	
	public void associate(ExtendedReference eRef, EReference ref) {
		associate_(eRef, ref);
	}
	
	public void associate(ExtendedAttribute eAtt, EAttribute att) {
		associate_(eAtt, att);
	}
	
	private void associate_(MetaElement metaElement, EStructuralFeature feature) {
		if (! (metaElement instanceof Adapter)) {
			return;
		}
		int sz = feature.eAdapters().size();
		for (int i = sz - 1; i >=0; i--) {
			Object adapter = feature.eAdapters().get(i);
			if (adapter instanceof MetaElement) {
				feature.eAdapters().remove(i);
			}
		}
		feature.eAdapters().add((Adapter) metaElement);
	}
	
	public ExtendedReference getAssociatedExtendedReference(EStructuralFeature feature) {
		MetaElement element = getAssociatedMetaElement(feature);
		if (element instanceof ExtendedReference) {
			return (ExtendedReference) element;
		}
		return null;
	}

	public ExtendedAttribute getAssociatedExtendedAttribute(EStructuralFeature feature) {
		MetaElement element = getAssociatedMetaElement(feature);
		if (element instanceof ExtendedAttribute) {
			return (ExtendedAttribute) element;
		}
		return null;
	}
	
	private MetaElement getAssociatedMetaElement(EStructuralFeature feature) {
		if (feature == null) {
			return null;
		}
		for (Object adapter : feature.eAdapters()) {
			if (adapter instanceof MetaElement) {
				return (MetaElement) adapter;
			}
		}
		return null;
	}
		
	public Object eGet(EObject obj, EStructuralFeature feature) {
		return eGet(obj, feature, false);
	}
	
	public Object eGet(EObject obj, EStructuralFeature feature, boolean toModify) {
		if (obj == null) {
			return null;
		}		
		if (obj instanceof MethodElement) {
			PropUtil propUtil = PropUtil.getPropUtil();
			MethodElement element = (MethodElement) obj;
			if (feature instanceof EReference) {
				EReference ref = (EReference) feature;
				if (element instanceof Practice) {
					PracticePropUtil practicePropUtil = PracticePropUtil.getPracticePropUtil();
					Practice practice = (Practice) element;
					UserDefinedTypeMeta meta = practicePropUtil.getUdtMeta(practice);
					if (meta != null && meta.isQualifiedRefernce((EReference) feature)) {
						List list = practicePropUtil.getQReferenceListById(element,
								feature.getName(), false);
						return list;
					}
				}								
				if (ref == UmaUtil.MethodElement_UdtList) {
					return propUtil.getUdtList(element, toModify);
				}
				ExtendedReference eRef = getAssociatedExtendedReference(ref);
				if (eRef != null) {
					return propUtil.getExtendedReferenceList(element, eRef, toModify);
				}
			} else if (feature instanceof EAttribute && element instanceof ContentDescription) {
				EAttribute att = (EAttribute) feature;
				ExtendedAttribute eAtt = getAssociatedExtendedAttribute(att);
				if (eAtt != null) {
					return propUtil.getExtendedAttribute((ContentDescription) element, eAtt);
				}
			}
		}
		return obj.eGet(feature);
	}
	
	public void eSet(EObject obj, EStructuralFeature feature, Object newValue) {
		if (obj instanceof ContentDescription) {
			ExtendedAttribute eAtt = getAssociatedExtendedAttribute(feature);
			if (eAtt != null && (newValue == null || newValue instanceof String) ) {
				PropUtil.getPropUtil().setExtendedAttribute((ContentDescription) obj, eAtt, (String) newValue);
				return;
			}
		}
		obj.eSet(feature, newValue);
	}
		
	public void eBasicSet(EObject obj, EStructuralFeature feature, Object newValue) {
		boolean oldB = obj.eDeliver();
		try {
			if (oldB) {
				obj.eSetDeliver(false);
			}
			eSet(obj, feature, newValue);
		} finally {
			if (oldB) {
				obj.eSetDeliver(true);
			}
		}
	}
	
	public List<EReference> getEAllReferences(MethodElement element) {
		List<EReference> list = new ArrayList<EReference>(element.eClass().getEAllReferences());
		
		if (element instanceof Practice) {
			PracticePropUtil practicePropUtil = PracticePropUtil.getPracticePropUtil();
			Practice practice = (Practice) element;
			UserDefinedTypeMeta meta = practicePropUtil.getUdtMeta(practice);
			if (meta != null && !meta.getQualifiedReferences().isEmpty()) {
				list.addAll(meta.getQualifiedReferences());
			}
		}
		
		PropUtil propUtil = PropUtil.getPropUtil();	
		
		list.add(UmaUtil.MethodElement_UdtList);
							
		ModifiedTypeMeta meta = propUtil.getGlobalMdtMeta(element);
		if (meta != null) {
			list = new ArrayList<EReference>(list);
			for (ExtendedReference eRef : meta.getReferences()) {
				list.add(eRef.getReference());
				for (QualifiedReference qRef : eRef.getQualifiedReferences()) {
					list.add(qRef.getReference());
				}
			}
		}
		return list;
	}
	
	public List<EAttribute> getEAllAttributes(MethodElement element) {
		List<EAttribute> list =new ArrayList<EAttribute>(element.eClass().getEAllAttributes());
		
		if (! (element instanceof ContentDescription)) {
			return list;
		}
					
		EObject owner = element.eContainer();
		if (! (owner instanceof MethodElement)) {
			return list;
		}
		
		PropUtil propUtil = PropUtil.getPropUtil();	
		ModifiedTypeMeta meta = propUtil.getGlobalMdtMeta((MethodElement) owner);
		if (meta == null) {
			return list;
		}
		for (ExtendedAttribute eAtt : meta.getRtes()) {
			list.add(eAtt.getAttribute());
		}
		
		return list;
	}
	
	public MethodElementExt createExtendObject(MethodElement element) {
		PropUtil propUtil = PropUtil.getPropUtil();
		if (propUtil.isWorkProductState(element)) {
			return new WorkProductStateExt((Constraint) element);
		}
		if (element instanceof Descriptor) {
			return new DescriptorExt((Descriptor) element);
		}
		if (element instanceof MethodPlugin) {
			return new MethodPluginExt((MethodPlugin) element);
		}
		return new MethodElementExt(element);
	}
		
	public static Class getSuperClass(Class cls) {
		Class cls1 = ContentElement.class;
		Class cls2 = BreakdownElement.class;
		Class[] ins = cls.getInterfaces();
		if (ins == null || ins.length == 0) {
			return null;
		}
		for (Class in : ins) {
			if (cls1.isAssignableFrom(in) || cls2.isAssignableFrom(in)) {
				return in;
			}
		}
		return null;
	}	
	
	public static ModifiedTypeMeta getMdtMeta(EClass cls) {
		try {
			MethodElement element = (MethodElement) UmaFactory.eINSTANCE
					.create(cls);
			return getMdtMeta(element);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static ModifiedTypeMeta getMdtMeta(MethodElement element) {		
		return PropUtil.getPropUtil().getGlobalMdtMeta(element);
	}
	
	public static ModifiedTypeMeta getLinkedMdtMeta(MethodElement element) {		
		ModifiedTypeMeta meta = getMdtMeta(element);
		if (meta == null) {
			return null;
		}
		Collection<ModifiedTypeMeta> allTypes = LibraryEditUtil.getInstance().getModifiedTypes();
		if (allTypes == null) {
			return null;
		}
		for (ModifiedTypeMeta oMeta : allTypes) {
			if (! oMeta.getLinkTypes().isEmpty() && meta.getId().equals(oMeta.getLinkTypes().get(0))) {
				return oMeta;
			}
		}
		return null;
	}
	
	public static boolean hasLinkTypes(MethodElement element) {
		ModifiedTypeMeta meta = getMdtMeta(element);
		if (meta == null) {
			return false;
		}
		return meta.getLinkTypes() != null && ! meta.getLinkTypes().isEmpty();
	}
	
	public static String getTypeId(MethodElement element) {
		if (element instanceof Practice) {
			UserDefinedTypeMeta meta = PracticePropUtil.getPracticePropUtil().getUdtMeta((Practice) element);
			if (meta != null) {
				return meta.getRteNameMap().get(UserDefinedTypeMeta._typeId);
			}
		}
		return element.eClass().getInstanceClass().getName();
	}
	
	public static boolean isTypeOf(MethodElement element, String typeId) {
		String elementTypeId = getTypeId(element);
		if (elementTypeId.equals(typeId)) {
			return true;
		}		
		for (EClass cls : element.eClass().getEAllSuperTypes()) {
			Class c = cls.getInstanceClass();
			if (c.getName().equals(typeId)) {
				return true;
			}
		}		
		return false;
	}
	
	public void validateId(String context, String id) throws TypeDefException {
		String errorMsg = checkIdValue(context, id);
		if (errorMsg != null) {
			throw new TypeDefException(errorMsg);
		}		
	}
	
	public String checkIdValue(String context, String id) {		
		if (id == null || id.trim().length() == 0) {
			return "Invalid id string for " + context + ": id cannot be null or empty!";//$NON-NLS-1$	//$NON-NLS-2$	
		}
		char c = id.charAt(0);
		if (! (c == '_' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
			return "Invalid id string for " + context + ": " + id + "\nid must start with an letter or underscore";//$NON-NLS-1$	//$NON-NLS-2$//$NON-NLS-3$		
		}		
		
		char lastC = c;
		for (int i = 1 ; i < id.length(); i++) {
			c = id.charAt(i);			
			boolean valid = (c == '_' || c == '-' || c == '.' || c >= '0' && c <= '9' || (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'));
			if (c == '.' && lastC == c) {
				valid = false;
			}
			if (! valid) {
				return "Invalid id string for " + context + ": " + id + "\nid can only contain letters, digits, underscores, hyphens, and single periods";//$NON-NLS-1$	//$NON-NLS-2$//$NON-NLS-3$		
			}
			lastC = c;
		}
		return null;
	}
	
	public ModifiedTypeMeta newModifiedTypeMeta() {
		return new ModifiedTypeMetaImpl();
	}
	
	private static String indent0 = "     ";  //$NON-NLS-1$
	public static String getMTypesDebugString(Collection<ModifiedTypeMeta> mtypes, String label) {
		List<ModifiedTypeMeta> list = new ArrayList<ModifiedTypeMeta>();
		if (mtypes != null) {
			list.addAll(mtypes);
		}
		Collections.sort(list);
				
		StringBuffer sb = new StringBuffer();
		if (label == null) {
			label = "";
		}
		sb.append(label + "\n"); 	//$NON-NLS-1$
		sb.append("size: " + list.size() + "\n"); 	//$NON-NLS-1$
		if (list.isEmpty()) {
			return sb.toString();
		}
		for (int i = 0; i < list.size(); i++) {
			ModifiedTypeMeta meta = list.get(i);
			sb.append(meta.getDebugString(i, indent0));
		}
				
		return sb.toString();
	}
	
}
