/*******************************************************************************
 * 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.resources.ResourcesPlugin;
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.EventResult;
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, ResourcesPlugin.getWorkspace());
                    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, ResourcesPlugin.getWorkspace());
            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);
        }
    }
}