/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IMapTypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ITypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.SymbolPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>IMap Type Descriptor</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IMapTypeDescriptorImpl#getMapSource <em>Map Source</em>}</li>
 *   <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IMapTypeDescriptorImpl#isImmutable <em>Immutable</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class IMapTypeDescriptorImpl extends ITypeDescriptorImpl implements IMapTypeDescriptor {
    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @SuppressWarnings("hiding")
	public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$

    /**
     * The default value of the '{@link #getMapSource() <em>Map Source</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getMapSource()
     * @generated
     * @ordered
     */
    protected static final Map MAP_SOURCE_EDEFAULT = null;

    /**
     * The cached value of the '{@link #getMapSource() <em>Map Source</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #getMapSource()
     * @generated
     * @ordered
     */
    protected Map mapSource = MAP_SOURCE_EDEFAULT;

    /**
     * The default value of the '{@link #isImmutable() <em>Immutable</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #isImmutable()
     * @generated
     * @ordered
     */
    protected static final boolean IMMUTABLE_EDEFAULT = true;

    private static final Object MAP_TYPE_DESCRIPTOR_PROP_KEY = new Object();

    /**
     * The cached value of the '{@link #isImmutable() <em>Immutable</em>}' attribute.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @see #isImmutable()
     * @generated
     * @ordered
     */
    protected boolean immutable = IMMUTABLE_EDEFAULT;

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    protected IMapTypeDescriptorImpl() {
        super();
    }

    /**
     * <!-- begin-user-doc -->
     * @return the static eClass 
     * <!-- end-user-doc -->
     * @generated
     */
    protected EClass eStaticClass() {
        return SymbolPackage.Literals.IMAP_TYPE_DESCRIPTOR;
    }

    /**
     * <!-- begin-user-doc -->
     * @return the map source 
     * <!-- end-user-doc -->
     * @generated
     */
    public Map getMapSource() {
        return mapSource;
    }

    /**
     * <!-- begin-user-doc -->
     * @param newMapSource 
     * <!-- end-user-doc -->
     * @generated
     */
    public void setMapSource(Map newMapSource) {
        Map oldMapSource = mapSource;
        mapSource = newMapSource;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE, oldMapSource, mapSource));
    }

    /**
     * <!-- begin-user-doc -->
     * @return true if this map is immutable as defined in the java.util.Map
     * interface. 
     * <!-- end-user-doc -->
     * @generated
     */
    public boolean isImmutable() {
        return immutable;
    }

    /**
     * <!-- begin-user-doc -->
     * @param newImmutable 
     * <!-- end-user-doc -->
     * @generated
     */
    public void setImmutable(boolean newImmutable) {
        boolean oldImmutable = immutable;
        immutable = newImmutable;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE, oldImmutable, immutable));
    }

    /* (non-Javadoc)
     * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature()
     * @generated NOT
     */
    public String getTypeSignature() 
    {
        // if the delegate has been set, use it
        if (eIsSet(SymbolPackage.IMAP_TYPE_DESCRIPTOR__TYPE_SIGNATURE_DELEGATE))
        {
            return getTypeSignatureDelegate();
        }
        
        // otherwise use Map
        return TypeConstants.TYPE_MAP;
    }

    public EList getInterfaceTypeSignatures() {
        return ECollections.EMPTY_ELIST;
    }

    public EList getSuperTypeSignatures() {
        return ECollections.EMPTY_ELIST;
    }

    /**
     * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getProperties()
     */
    public EList getProperties()
    {
        final BasicEList list = new BasicEList();
        final Map source = getMapSource();
        if (source instanceof IMapSourceInfo)
        {
            if (!((IMapSourceInfo) source).hasChanged(MAP_TYPE_DESCRIPTOR_PROP_KEY))
            {
                EList cachedList = (EList) ((IMapSourceInfo)source).getCachedValue(MAP_TYPE_DESCRIPTOR_PROP_KEY);

                if (cachedList != null)
                {
                    return cachedList;
                }
            }
        }
        final Map segmentMap = processSegments(source);
        list.addAll(segmentMap.values());

        if (source instanceof IMapSourceInfo)
        {
            ((IMapSourceInfo)source).putCachedValue(MAP_TYPE_DESCRIPTOR_PROP_KEY, list);
        }
        return list;
    }

    public EList getMethods() 
    {
        // TODO: should this return the methods on  a Map?
        return ECollections.EMPTY_ELIST;
    }
    
    /**
     * @generated NOT
     */
    public IObjectSymbol getArrayElement()
    {
        return null;
    }

    /**
     * @generated NOT
     */
    public boolean isArray()
    {
        // a map is never an array
        return false;
    }

    private Map processSegments(final Map source)
    {
        final Map segmentMap = new HashMap();
        final Set<Map.Entry<String, Object>> entrySet = source.entrySet();
        for (final Map.Entry<String, Object> entry : entrySet)
        {

            final String key = entry.getKey();
            final String segments[] = fastTokenSplit(key);
            if (segments.length == 0)
            {
                continue;
            }
            IPropertySymbol property = (IPropertySymbol) segmentMap
                    .get(segments[0]);

            if (property == null)
            {
                final Object propValue = entry.getValue();
                property = SymbolFactory.eINSTANCE.createIPropertySymbol();
                property.setName(segments[0]);
                ITypeDescriptor typeDesc = null;

                // TODO: need wrapper object to rationalize
                if (propValue != null)
                {
                    if (propValue instanceof IType)
                    {
                        typeDesc = SymbolFactory.eINSTANCE
                                .createIJavaTypeDescriptor2();
                        ((IJavaTypeDescriptor2) typeDesc)
                                .setType((IType) propValue);
                    } else if (propValue instanceof IInstanceSymbol)
                    {
                        typeDesc = ((IInstanceSymbol) propValue)
                                .getTypeDescriptor();
                    } else if (propValue instanceof IPropertySymbol)
                    {
                        typeDesc = ((IPropertySymbol) propValue)
                                .getTypeDescriptor();
                    } else
                    {
                        final String className = propValue.getClass().getName();
                        final String typeSignature = Signature
                                .createTypeSignature(className, true);
                        typeDesc = SymbolFactory.eINSTANCE
                                .createIMapTypeDescriptor();
                        ((IMapTypeDescriptor) typeDesc)
                                .setMapSource(new HashMap());
                        ((IMapTypeDescriptor) typeDesc)
                                .setTypeSignatureDelegate(typeSignature);
                        // inherit this descriptor's mutability
                        ((IMapTypeDescriptor) typeDesc)
                                .setImmutable(isImmutable());
                        property.setIntermediate(true); // set the property as
                        // intermediate until we
                        // find out different
                    }

                    property.setTypeDescriptor(typeDesc);
                    property.setReadable(true);
                    // is only writable if map is not immutable
                    property.setWritable(!isImmutable());
                }

                segmentMap.put(segments[0], property);
            }

            final ITypeDescriptor typeDesc = property.getTypeDescriptor();

            if (typeDesc instanceof IMapTypeDescriptor)
            {
                if (segments.length == 1)
                {
                    // TODO: not always allowed
                    // ((IMapTypeDescriptor)typeDesc).getMapSource().put(null,
                    // source.get(key));
                    // property is more than simply intermediate
                    property.setIntermediate(false);
                } else
                {
                    ((IMapTypeDescriptor) typeDesc).getMapSource().put(
                            key.substring(key.indexOf('.') + 1),
                            entry.getValue());
                }
            }
        }

        return segmentMap;
    }

    /**
     * Based on measurements, this beats Pattern.split by 15-30% even with
     * a pre-compiled pattern.
     * 
     * @param splitValue
     * @return the array of strings split by the '.' token
     */
    private static String[] fastTokenSplit(final String splitValue)
    {
        if (splitValue == null || splitValue.length() == 0)
        {
            return new String[0];
        }
        if (splitValue.indexOf('.') > -1)
        {
            return tokenizerSplit(splitValue);
        }
        return new String[] {splitValue};
    }

    private static String[] tokenizerSplit(final String splitValue)
    {
        StringTokenizer stringTokenizer = new StringTokenizer(splitValue, ".");
        // initialize to a large size, since we're just going to truncate
        // it once at the end and want to reduce the chance of resize during
        // the loop.
        final List<String> splitValues = new ArrayList<String>(32);

        while (stringTokenizer.hasMoreTokens())
        {
            splitValues.add(stringTokenizer.nextToken());
        }

        return splitValues.toArray(new String[0]);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @param resolve 
     * @param coreType 
     * @return the object for the feature id 
     * <!-- end-user-doc -->
     * @generated
     */
    public Object eGet(int featureID, boolean resolve, boolean coreType) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                return getMapSource();
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                return isImmutable() ? Boolean.TRUE : Boolean.FALSE;
        }
        return super.eGet(featureID, resolve, coreType);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @param newValue 
     * <!-- end-user-doc -->
     * @generated
     */
    public void eSet(int featureID, Object newValue) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                setMapSource((Map)newValue);
                return;
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                setImmutable(((Boolean)newValue).booleanValue());
                return;
        }
        super.eSet(featureID, newValue);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * <!-- end-user-doc -->
     * @generated
     */
    public void eUnset(int featureID) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                setMapSource(MAP_SOURCE_EDEFAULT);
                return;
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                setImmutable(IMMUTABLE_EDEFAULT);
                return;
        }
        super.eUnset(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * @param featureID 
     * @return true if is set
     * <!-- end-user-doc -->
     * @generated
     */
    public boolean eIsSet(int featureID) {
        switch (featureID) {
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__MAP_SOURCE:
                return MAP_SOURCE_EDEFAULT == null ? mapSource != null : !MAP_SOURCE_EDEFAULT.equals(mapSource);
            case SymbolPackage.IMAP_TYPE_DESCRIPTOR__IMMUTABLE:
                return immutable != IMMUTABLE_EDEFAULT;
        }
        return super.eIsSet(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * @return the string representation 
     * <!-- end-user-doc -->
     * @generated
     */
    public String toString() {
        if (eIsProxy()) return super.toString();

        StringBuffer result = new StringBuffer(super.toString());
        result.append(" (mapSource: "); //$NON-NLS-1$
        result.append(mapSource);
        result.append(", immutable: ");  //$NON-NLS-1$
        result.append(immutable);
        result.append(')');
        return result.toString();
    }

} //IMapTypeDescriptorImpl
