/**
 */
package org.etsi.mts.tdl.impl;

import java.util.Iterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.library.executor.ExecutorSingleIterationManager;
import org.eclipse.ocl.pivot.library.AbstractBinaryOperation;
import org.eclipse.ocl.pivot.library.LibraryIteration.LibraryIterationExtension;
import org.eclipse.ocl.pivot.library.classifier.ClassifierOclContainerOperation;
import org.eclipse.ocl.pivot.library.collection.CollectionAsOrderedSetOperation;
import org.eclipse.ocl.pivot.library.collection.OrderedCollectionFirstOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclAsSetOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclAsTypeOperation;
import org.eclipse.ocl.pivot.library.oclany.OclAnyOclIsKindOfOperation;
import org.eclipse.ocl.pivot.library.string.StringConcatOperation;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.InvalidValueException;
import org.eclipse.ocl.pivot.values.OrderedSetValue;
import org.eclipse.ocl.pivot.values.SetValue;
import org.eclipse.ocl.pivot.values.SetValue.Accumulator;
import org.etsi.mts.tdl.NamedElement;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.tdlTables;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Named Element</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.etsi.mts.tdl.impl.NamedElementImpl#getQualifiedName <em>Qualified Name</em>}</li>
 * </ul>
 *
 * @generated
 */
public abstract class NamedElementImpl extends ElementImpl implements NamedElement
{
	/**
	 * The default value of the '{@link #getQualifiedName() <em>Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String QUALIFIED_NAME_EDEFAULT = null;
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected NamedElementImpl()
	{
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass()
	{
		return tdlPackage.Literals.NAMED_ELEMENT;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getQualifiedName()
	{
		/**
		 *
		 * if self.name.oclIsUndefined()
		 * then ''
		 * else
		 *   if not self.oclContainer().oclIsUndefined()
		 *   then
		 *     if self.oclContainer().oclIsKindOf(NamedElement)
		 *     then
		 *       self.oclContainer()
		 *       .oclAsType(NamedElement).qualifiedName + '::' + self.name
		 *     else
		 *       self.oclContainer()
		 *       .oclAsType(OclElement)
		 *       ->closure(oclContainer())
		 *       ->select(c | c.oclIsKindOf(NamedElement))
		 *       ->asOrderedSet()
		 *       ->first()
		 *       .oclAsType(NamedElement).qualifiedName + '::' + self.name
		 *     endif
		 *   else self.name
		 *   endif
		 * endif
		 */
		final /*@NonInvalid*/ Executor executor = PivotUtil.getExecutor(this);
		final /*@NonInvalid*/ IdResolver idResolver = executor.getIdResolver();
		final /*@NonInvalid*/ String name_2 = this.getName();
		final /*@NonInvalid*/ StandardLibrary standardLibrary = idResolver.getStandardLibrary();
		final /*@NonInvalid*/ boolean oclIsUndefined = name_2 == null;
		/*@Thrown*/ String local_2;
		if (oclIsUndefined) {
			local_2 = tdlTables.STR_;
		}
		else {
			final /*@NonInvalid*/ Object oclContainer_0 = ClassifierOclContainerOperation.INSTANCE.evaluate(executor, this);
			final /*@NonInvalid*/ boolean oclIsUndefined_0 = oclContainer_0 == null;
			final /*@NonInvalid*/ Boolean not;
			if (!oclIsUndefined_0) {
				not = ValueUtil.TRUE_VALUE;
			}
			else {
				if (oclIsUndefined_0) {
					not = ValueUtil.FALSE_VALUE;
				}
				else {
					not = null;
				}
			}
			if (not == null) {
				throw new InvalidValueException("Null if condition");
			}
			/*@Thrown*/ String local_1;
			if (not) {
				final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_tdl_c_c_NamedElement_0 = idResolver.getClass(tdlTables.CLSSid_NamedElement, null);
				final /*@Thrown*/ boolean oclIsKindOf = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, oclContainer_0, TYP_tdl_c_c_NamedElement_0).booleanValue();
				/*@Thrown*/ String local_0;
				if (oclIsKindOf) {
					final /*@Thrown*/ NamedElement oclAsType = (NamedElement)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, oclContainer_0, TYP_tdl_c_c_NamedElement_0);
					final /*@Thrown*/ String qualifiedName = oclAsType.getQualifiedName();
					final /*@Thrown*/ String sum = StringConcatOperation.INSTANCE.evaluate(qualifiedName, tdlTables.STR__c_c);
					final /*@Thrown*/ String sum_0 = StringConcatOperation.INSTANCE.evaluate(sum, name_2);
					local_0 = sum_0;
				}
				else {
					final /*@NonInvalid*/ org.eclipse.ocl.pivot.Class TYP_OclElement_0 = idResolver.getClass(tdlTables.CLSSid_OclElement, null);
					final /*@Thrown*/ Object oclAsType_0 = OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, oclContainer_0, TYP_OclElement_0);
					final /*@Thrown*/ SetValue oclAsSet = OclAnyOclAsSetOperation.INSTANCE.evaluate(executor, tdlTables.SET_CLSSid_OclElement, oclAsType_0);
					final org.eclipse.ocl.pivot.Class TYPE_closure_0 = executor.getStaticTypeOfValue(null, oclAsSet);
					final LibraryIterationExtension IMPL_closure_0 = (LibraryIterationExtension)TYPE_closure_0.lookupImplementation(standardLibrary, OCLstdlibTables.Operations._Set__closure);
					final /*@NonNull*/ Object ACC_closure_0 = IMPL_closure_0.createAccumulatorValue(executor, tdlTables.SET_CLSSid_OclElement, tdlTables.CLSSid_OclElement);
					/**
					 * Implementation of the iterator body.
					 */
					final AbstractBinaryOperation BODY_closure_0 = new AbstractBinaryOperation() {
						/**
						 * oclContainer()
						 */
						@Override
						public /*@Nullable*/ Object evaluate(final Executor executor, final TypeId typeId, final /*@Nullable*/ Object oclAsSet, final /*@NonInvalid*/ Object _1) {
							if (_1 == null) {
								throw new InvalidValueException("Null \'\'OclElement\'\' rather than \'\'OclVoid\'\' value required");
							}
							final /*@Thrown*/ Object oclContainer_3 = ClassifierOclContainerOperation.INSTANCE.evaluate(executor, _1);
							return oclContainer_3;
						}
					};
					final ExecutorSingleIterationManager MGR_closure_0 = new ExecutorSingleIterationManager(executor, tdlTables.SET_CLSSid_OclElement, BODY_closure_0, oclAsSet, ACC_closure_0);
					final /*@Thrown*/ SetValue closure = (SetValue)IMPL_closure_0.evaluateIteration(MGR_closure_0);
					/*@Thrown*/ Accumulator accumulator = ValueUtil.createSetAccumulatorValue(tdlTables.SET_CLSSid_OclElement);
					Iterator<Object> ITERATOR_c = closure.iterator();
					/*@Thrown*/ SetValue select;
					while (true) {
						if (!ITERATOR_c.hasNext()) {
							select = accumulator;
							break;
						}
						/*@NonInvalid*/ Object c = (Object)ITERATOR_c.next();
						/**
						 * c.oclIsKindOf(NamedElement)
						 */
						final /*@Thrown*/ boolean oclIsKindOf_0 = OclAnyOclIsKindOfOperation.INSTANCE.evaluate(executor, c, TYP_tdl_c_c_NamedElement_0).booleanValue();
						//
						if (oclIsKindOf_0 == ValueUtil.TRUE_VALUE) {
							accumulator.add(c);
						}
					}
					final /*@Thrown*/ OrderedSetValue asOrderedSet = CollectionAsOrderedSetOperation.INSTANCE.evaluate(select);
					final /*@Thrown*/ Object first = OrderedCollectionFirstOperation.INSTANCE.evaluate(asOrderedSet);
					final /*@Thrown*/ NamedElement oclAsType_1 = (NamedElement)OclAnyOclAsTypeOperation.INSTANCE.evaluate(executor, first, TYP_tdl_c_c_NamedElement_0);
					final /*@Thrown*/ String qualifiedName_0 = oclAsType_1.getQualifiedName();
					final /*@Thrown*/ String sum_1 = StringConcatOperation.INSTANCE.evaluate(qualifiedName_0, tdlTables.STR__c_c);
					final /*@Thrown*/ String sum_2 = StringConcatOperation.INSTANCE.evaluate(sum_1, name_2);
					local_0 = sum_2;
				}
				local_1 = local_0;
			}
			else {
				local_1 = name_2;
			}
			local_2 = local_1;
		}
		if (local_2 == null) {
			throw new InvalidValueException("Null body for \'tdl::NamedElement::qualifiedName\'");
		}
		return local_2;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType)
	{
		switch (featureID) {
			case tdlPackage.NAMED_ELEMENT__QUALIFIED_NAME:
				return getQualifiedName();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID)
	{
		switch (featureID) {
			case tdlPackage.NAMED_ELEMENT__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
		}
		return super.eIsSet(featureID);
	}

} //NamedElementImpl
