/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view.model.jsp.registry;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jst.jsf.common.internal.policy.OrderedListProvider;
import org.eclipse.jst.jsf.common.internal.policy.OrderedListProvider.OrderableObject;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.DefaultJSPTagResolver;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TagIntrospectingStrategy;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.JSPTagResolvingStrategy.StrategyDescriptor;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.persistence.PersistedDataTagStrategy;

/**
 * Preferences model for the TLD registry.  This class is not thread-safe and
 * a single instance should only be used by one owner.
 * 
 * @author cbateman
 * 
 */
public class TLDRegistryPreferences
{
    private final static Map<String, StrategyDescriptor> ALL_KNOWN_STRATEGIES;

    private final IPreferenceStore             _prefStore;
    private final CopyOnWriteArrayList<PropertyListener> _listeners;
    private final AtomicBoolean                _isDisposed = new AtomicBoolean(false);

    private final static String                KEY_STRATEGY_ID_ORDER = "org.eclipse.jst.jsf.designtime.jsp.registry.StrategyIDOrder"; //$NON-NLS-1$

    private final static List<OrderableObject> DEFAULT_STRATEGY_ORDER;

    static
    {
        final List<OrderableObject> list = new ArrayList<OrderableObject>();

        // NOTE !!! this ordering is important and effects the default order
        // in which strategies will be consulted !!!
        list.add(new OrderableObject(new StrategyIdentifier(PersistedDataTagStrategy.createDescriptor()), true));
        list.add(new OrderableObject(new StrategyIdentifier(DefaultJSPTagResolver.createDescriptor()), true));
        // Bug 312954 - temporarily disable the default preference for the
        // TagIntrospectingStrategy. When bug 312936 and 240394 get resolved,
        // roll back this change and re-enable.
        list.add(new OrderableObject(new StrategyIdentifier(TagIntrospectingStrategy.createDescriptor()), false));
        DEFAULT_STRATEGY_ORDER = Collections.unmodifiableList(list);
        

        final Map<String, StrategyDescriptor> knownDescriptors = new HashMap<String, StrategyDescriptor>();
        for (final OrderableObject object : DEFAULT_STRATEGY_ORDER)
        {
            StrategyIdentifier strategyId = (StrategyIdentifier) object.getObject();
            knownDescriptors.put(strategyId.getId(), strategyId._descriptor);
        }
        ALL_KNOWN_STRATEGIES = Collections.unmodifiableMap(knownDescriptors);
    }

    private List<OrderableObject>              _ids;
    private List<OrderableObject>              _originalIds;
    private IPropertyChangeListener            _propertyListener;

    /**
     * Constructor
     * 
     * @param prefStore
     */
    public TLDRegistryPreferences(final IPreferenceStore prefStore)
    {
        _prefStore = prefStore;
        _ids = new ArrayList<OrderableObject>();
        _listeners = new CopyOnWriteArrayList<PropertyListener>();
    }

    /**
     * Dispose of this preferences object
     */
    public void dispose()
    {
        if (_isDisposed.compareAndSet(false, true))
        {
            if (_propertyListener != null)
            {
                _prefStore.removePropertyChangeListener(_propertyListener);
            }
        }
    }

    void addListener(final PropertyListener propListener)
    {
        if (!assertNotDisposed())
        {
            return;
        }

        if (_propertyListener == null)
        {
            _propertyListener = new IPropertyChangeListener()
            {
                public void propertyChange(PropertyChangeEvent event)
                {
                    if (KEY_STRATEGY_ID_ORDER.equals(event.getProperty()))
                    {
                        fireStrategyOrderChanged();
                    }
                }
            };
            
            _prefStore.addPropertyChangeListener(_propertyListener);
        }
        _listeners.addIfAbsent(propListener);
    }

    void removeListener(final PropertyListener propListener)
    {
        if (!assertNotDisposed())
        {
            return;
        }
        _listeners.remove(propListener);

        if (_listeners.isEmpty())
        {
            _prefStore.removePropertyChangeListener(_propertyListener);
            _propertyListener = null;
        }
    }

    private void fireStrategyOrderChanged()
    {
        if (!assertNotDisposed())
        {
            return;
        }
        for (final PropertyListener listener : _listeners)
        {
            listener.strategyOrderChanged();
        }
    }

    /**
     * @return false if the assertion fails
     */
    private boolean assertNotDisposed()
    {
        if (_isDisposed.get())
        {
            JSFCorePlugin.log(new Exception("Stack trace only"), "TLDRegistryPreferences is disposed"); //$NON-NLS-1$ //$NON-NLS-2$
            return false;
        }
        return true;
    }

    /**
     * IPreferenceStore The default preference loader
     */
    public void load()
    {
        load(_prefStore);
    }

    /**
     * @return the ordered list provider for the strategy id ordering
     */
    public OrderedListProvider getOrderedListProvider()
    {
        return new MyOrderedListProvider();
    }

    /**
     * @return the strategy id ordering
     */
    public List<OrderableObject> getStrategyIdOrdering()
    {
        return _ids;
    }

    /**
     * @param ids
     */
    public void setStrategyIdOrdering(final List<OrderableObject> ids)
    {
        _ids = ids;
    }

    /**
     * @return the list of strategy ids in the order they should be consulted
     */
    public List<String> getEnabledIds()
    {
        final List<String> strategies = new ArrayList<String>();

        for (final OrderableObject id : _ids)
        {
            if (id.isEnabled())
            {
                StrategyIdentifier strategyId = (StrategyIdentifier) id.getObject();
                strategies.add(strategyId.getId());
            }
        }
        return strategies;
    }

    /**
     * Loads preferences from prefStore
     * 
     * @param prefStore
     */
    private void load(final IPreferenceStore prefStore)
    {
        if (!prefStore.contains(KEY_STRATEGY_ID_ORDER))
        {
            prefStore.setDefault(KEY_STRATEGY_ID_ORDER,
                    serialize(DEFAULT_STRATEGY_ORDER));
        }
        List<OrderableObject> ids = deserialize(prefStore
                .getString(KEY_STRATEGY_ID_ORDER));
        if (ids == null)
        {
            ids = deserialize(serialize(DEFAULT_STRATEGY_ORDER));
        }
        _ids = ids;
        final List<OrderableObject> originalList = new ArrayList<OrderableObject>();
        for (final OrderableObject id : _ids)
        {
            final OrderableObject copy = id.clone();
            originalList.add(copy);
        }
        _originalIds = Collections.unmodifiableList(originalList);
    }

    private String serialize(final List<OrderableObject> ids)
    {
        final StringBuffer buffer = new StringBuffer();

        for (final OrderableObject id : ids)
        {
            StrategyIdentifier strategyId = (StrategyIdentifier) id.getObject();
            buffer.append("dummyValue"); //$NON-NLS-1$
            buffer.append(","); //$NON-NLS-1$
            buffer.append(strategyId.getId());
            buffer.append(","); //$NON-NLS-1$
            buffer.append(id.isEnabled());
            buffer.append(","); //$NON-NLS-1$
        }
        return buffer.toString();
    }

    private List<OrderableObject> deserialize(final String serializedList)
    {
        final List<OrderableObject> list = new ArrayList<OrderableObject>();
        final String[] ids = serializedList.split(","); //$NON-NLS-1$
        if ((ids.length % 3) != 0)
        {
            return null;
        }

        for (int i = 0; i < ids.length; i += 3)
        {
            /// ingore the dummy value: final String displayName = ids[i];
            String id = ids[i + 1];
            final String enabled = ids[i + 2];

            // fix old id for meta-data resolver
            if ("org.eclipse.jst.jsf.THISISTEMPORARY".equals(id)) //$NON-NLS-1$
            {
                id = DefaultJSPTagResolver.ID;
            }

            final StrategyDescriptor desc = ALL_KNOWN_STRATEGIES.get(id);
            
            if (desc == null)
            {
                JSFCorePlugin.log(new Exception("Stack trace only"), "Error: unknown strategy id: "+id); //$NON-NLS-1$ //$NON-NLS-2$
            }
            else
            {
                final StrategyIdentifier strategyIdentifier = new StrategyIdentifier(desc);
                list.add(new OrderableObject(strategyIdentifier
                        , Boolean.valueOf(enabled).booleanValue()));
            }
        }
        return list;
    }

    /**
     * Commits but does not store the preferences
     * 
     * @param prefStore
     */
    public void commit(final IPreferenceStore prefStore)
    {
        prefStore.setValue(KEY_STRATEGY_ID_ORDER,
                serialize(getStrategyIdOrdering()));
        // refresh local copy of preferences
        load();
    }

    /**
     * Reverts the model to it's defaults. Does not commit to pref store.
     */
    public void setDefaults()
    {
         setStrategyIdOrdering(new ArrayList<OrderableObject>(
                DEFAULT_STRATEGY_ORDER));
    }

    /**
     * @return true if this preference object's properties have
     * changed since load() was last called.
     */
    public boolean isDirty()
    {
        // dirty if the current list is not equal to the original list
        // generated at load time.
        return !(_ids.equals(_originalIds));
    }

    /**
     * Used as the model for sorting and enabling strategy identifiers.
     * 
     */
    public static class StrategyIdentifier
    {
        private final StrategyDescriptor _descriptor;

        StrategyIdentifier(final StrategyDescriptor descriptor)
        {
            _descriptor = descriptor;
        }

        /**
         * @return the id
         */
        public String getId()
        {
            return _descriptor.getId();
        }

        @Override
        public boolean equals(Object obj)
        {
            if (obj instanceof StrategyIdentifier)
            {
                return getId().equals(((StrategyIdentifier)obj).getId());
            }
            return false;
        }

        @Override
        public int hashCode()
        {
            return getId().hashCode();
        }

        /**
         * @return the display name of the strategy
         */
        public String getDisplayName()
        {
            return _descriptor.getDisplayName();
        }
    }

    private class MyOrderedListProvider extends OrderedListProvider
    {
        @Override
        protected List<OrderableObject> createAndPopulateOrderedObjects()
        {
            return _ids;
        }
    }

    static abstract class PropertyListener
    {
        public abstract void strategyOrderChanged();
    }
}
