/*******************************************************************************
 * 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.designtime.internal.symbols;

import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.context.symbol.internal.impl.IMapSourceInfo;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.tld.LoadBundleUtil;

class ResourceBundleMapSource extends AbstractMap implements IMapSourceInfo
{
    private static final String   PROPERTY_QUALIFIER =
    	"org.eclipse.jst.jsf.designtime.internal.jsp"; //$NON-NLS-1$
    private static final String   SESSION_PROPERTY_NAME_PROJECT =
    	"ResourceBundleMapSource"; //$NON-NLS-1$
    private static final QualifiedName  SESSION_PROPERTY_KEY_PROJECT =
        new QualifiedName(PROPERTY_QUALIFIER, SESSION_PROPERTY_NAME_PROJECT);
    private static final Object  STATIC_LOCK = new Object();

    private static IFile    getCachedBundleFile(final IProject project, final String baseName)
    {
        if (project != null)
        {
            final Map<String, BundleFileCacheInfo> bundleFileCache = getBundleFileCache(project);

            if (bundleFileCache != null)
            {
                final BundleFileCacheInfo info = bundleFileCache.get(baseName);
                if (info != null)
                {
                    return info.getFile();
                }
            }
        }

        return null;
    }

    private static class BundleFileCacheInfo
    {
        private final IFile                 _file;
        private final Map<Object,CachedDataItem>    _cachedData;
        public BundleFileCacheInfo(final IFile file)
        {
            super();
            _file = file;
            _cachedData =
                Collections.synchronizedMap(new HashMap<Object, CachedDataItem>());
        }
        public IFile getFile()
        {
            return _file;
        }
        public Object getCachedData(final Object key)
        {
            CachedDataItem item = _cachedData.get(key);
            
            if (item != null)
            {
                return item.getData();
            }
            return null;
        }

        public Object putCachedData(final Object key, final Object value, final long timestamp)
        {
            CachedDataItem item = new CachedDataItem(value, timestamp);
            CachedDataItem oldItem = _cachedData.put(key, item);
            if (oldItem != null)
            {
                return oldItem.getData();
            }
            return null;
        }

        public boolean hasChanged(final Object key, final long timestamp)
        {
            CachedDataItem item = _cachedData.get(key);
            if (item != null)
            {
                return item.getTimestamp() != timestamp;
            }
            return false;
        }

        private static class CachedDataItem
        {
            private final Object        _data;
            private final long          _timestamp;
            public CachedDataItem(Object data, long timestamp)
            {
                super();
                _data = data;
                _timestamp = timestamp;
            }
            public final Object getData()
            {
                return _data;
            }
            public final long getTimestamp()
            {
                return _timestamp;
            }
        }
    }

    private static Map<String, BundleFileCacheInfo> getBundleFileCache(final IProject project)
    {
        synchronized(STATIC_LOCK)
        {
            Map<String, BundleFileCacheInfo> bundleFileCache = null;

            try
            {
                bundleFileCache =
                    (Map<String, BundleFileCacheInfo>) project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT);

                if (bundleFileCache == null)
                {
                    bundleFileCache = new HashMap<String, BundleFileCacheInfo>();
                    final LifecycleListener listener = new LifecycleListener(project);
                    listener.addListener(new IResourceLifecycleListener()
                    {
                        public EventResult acceptEvent(final ResourceLifecycleEvent event)
                        {
                            EventResult result = EventResult.getDefaultEventResult();

                            if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE)
                            {
                                try
                                {
                                	//Bug 283764: this listener may be called more than once - check project not already inaccessible
                                	if (project.isAccessible())
                                	{
	                                    final Map<String, BundleFileCacheInfo> bundleCache =
	                                        (Map<String, BundleFileCacheInfo>) project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT);
	                                    //This listener may be called more than once - check session property not already nulled
	                                    if (bundleCache != null)
	                                    {
	                                    	bundleCache.clear();
	                                        project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, null);
	                                    }
                                	}
                                }
                                catch (final CoreException ce)
                                {
                                    JSFCorePlugin.log("Error clearing bundle file cache", ce); //$NON-NLS-1$
                                }
                                result = EventResult.getDisposeAfterEventResult();
                            }

                            return result;
                        }
                    }
                    );

                    project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, bundleFileCache);
                }
            }
            catch (final CoreException ce)
            {
                JSFCorePlugin.log("Error creating bundle file cache", ce); //$NON-NLS-1$
            }

            return bundleFileCache;
        }
    }

    private static IFile createCachedBundleFile(final IProject project,
                                                   final String  resourcePathStr)
                      throws IOException, CoreException
    {
        final IStorage storage =
            LoadBundleUtil.getLoadBundleResource(project, resourcePathStr);

        IFile bundleRes = null;

        if (storage != null
                && storage.getAdapter(IFile.class) != null)
        {
            bundleRes = (IFile) storage.getAdapter(IFile.class);
            // if file is removed, clear the bundle from the store.
            final LifecycleListener listener = new LifecycleListener(bundleRes);
            listener.addListener(new IResourceLifecycleListener()
            {
                public EventResult acceptEvent(final ResourceLifecycleEvent event)
                {
                    EventResult result = EventResult.getDefaultEventResult();

                    if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE)
                    {
                        Map<String, BundleFileCacheInfo> bundleFileCache = getBundleFileCache(project);
                        bundleFileCache.remove(resourcePathStr);
                        result = EventResult.getDisposeAfterEventResult();
                    }
                    return result;
                }
            }
            );

            getBundleFileCache(project).put(resourcePathStr, new BundleFileCacheInfo(bundleRes));
            return bundleRes;
        }

        throw new IOException("Bundle "+resourcePathStr+" not found in classpath for project: "+project.getName()); //$NON-NLS-1$ //$NON-NLS-2$
    }

    private Properties                  _resourceBundle; // = null; set on first access or changes
    private final IFile                 _bundleFile;   // the resource
    private final String                _resourcePathStr; // the key used in the file cache
    // as returned by IResource.getModificationStamp()
    // the last time _resourceBundle was loaded
    private long                        _lastModificationStamp;

    ResourceBundleMapSource(final IProject context,
                            final String  resourcePathStr)
                                throws IOException, JavaModelException, CoreException
    {
        IFile cachedBundleFile = getCachedBundleFile(context, resourcePathStr);

        if (cachedBundleFile == null)
        {
            cachedBundleFile = createCachedBundleFile(context, resourcePathStr);
        }

        _bundleFile = cachedBundleFile;
        _resourcePathStr = resourcePathStr;
    }

    private void checkAndRefreshBundle()
    {
        if (_bundleFile.isAccessible())
        {
            if (_resourceBundle == null  // doesn't exist yet
                    // exists but ws is out of sync
                    || !_bundleFile.isSynchronized(IResource.DEPTH_ZERO)
                    // exists but user has changed in workspace
                    || _bundleFile.getModificationStamp() 
                            != _lastModificationStamp)
            {
                InputStream  bundleStream = null;
                try
                {
                    // force refresh if out of sync
                    bundleStream = _bundleFile.getContents(true);
                    _resourceBundle = new Properties();
                    _resourceBundle.load(bundleStream);
                    _lastModificationStamp = _bundleFile.getModificationStamp();
                }
                catch (final CoreException ce)
                {
                    JSFCorePlugin.log("Error refreshing bundle", ce); //$NON-NLS-1$
                }
                catch (final IOException ioe)
                {
                    JSFCorePlugin.log("Error refreshing bundle", ioe); //$NON-NLS-1$
                }
                finally
                {
                    if (bundleStream != null)
                    {
                        try
                        {
                            bundleStream.close();
                        }
                        catch (final IOException ioe)
                        {
                            JSFCorePlugin.log("Error closing bundle", ioe); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
        else
        {
            // bundle no longer exists so remove it
            final Map<String, BundleFileCacheInfo> bundleFileCache = getBundleFileCache(_bundleFile.getProject());

            if (bundleFileCache != null &&
                    bundleFileCache.containsKey(_resourcePathStr))
            {
                bundleFileCache.remove(_resourcePathStr);
            }
            // in either case, clear the bundle entry
            if (_resourceBundle != null)
            {
                _resourceBundle.clear();
                _resourceBundle = null;
            }
        }
    }

    @Override
    public Set entrySet()
    {
        checkAndRefreshBundle();

        if (_resourceBundle == null)
        {
        	return Collections.EMPTY_SET;
        }
        return _resourceBundle.entrySet();
    }

    /**
     * @param key
     * @return the value
     * @see java.util.AbstractMap#get(java.lang.Object)
     * @overrride to optimize for the fact that we are doing a hash get
     */
    //
    @Override
    public Object get(final Object key)
    {
        checkAndRefreshBundle();

        if (_resourceBundle == null)
        {
        	return null;
        }
        return _resourceBundle.get(key);
    }

    public final boolean hasChanged(final Object key)
    {
        final BundleFileCacheInfo cache = getBundleFileCache(
                _bundleFile.getProject()).get(_resourcePathStr);
        if (cache != null)
        {
            return cache.hasChanged(key, _bundleFile.getModificationStamp());
        }
        // return true since if there is nothing cached, the caller will want 
        // to react.
        return true;
    }

    public Object getCachedValue(final Object key)
    {
        final BundleFileCacheInfo cache = getBundleFileCache(
                _bundleFile.getProject()).get(_resourcePathStr);
        if (cache != null)
        {
            return cache.getCachedData(key);
        }
        return null;
    }

    public void putCachedValue(final Object key, final Object value)
    {
        final BundleFileCacheInfo cache = getBundleFileCache(
                _bundleFile.getProject()).get(_resourcePathStr);
        if (cache != null)
        {
            cache.putCachedData(key, value, _lastModificationStamp);
        }
    }
}