/*******************************************************************************
 * 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));
        list.add(new OrderableObject(new StrategyIdentifier(TagIntrospectingStrategy.createDescriptor()), true));
        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();
    }
}
