/*******************************************************************************
 * Copyright (c) 2012 Alexej Strelzow.
 * 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:
 *     Alexej Strelzow - initial API and implementation
 ******************************************************************************/
package org.eclipse.babel.core.message.manager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.babel.core.configuration.DirtyHack;
import org.eclipse.babel.core.factory.MessagesBundleGroupFactory;
import org.eclipse.babel.core.message.IMessage;
import org.eclipse.babel.core.message.IMessagesBundle;
import org.eclipse.babel.core.message.IMessagesBundleGroup;
import org.eclipse.babel.core.message.internal.Message;
import org.eclipse.babel.core.message.internal.MessagesBundle;
import org.eclipse.babel.core.message.internal.MessagesBundleGroup;
import org.eclipse.babel.core.refactoring.IRefactoringService;
import org.eclipse.babel.core.util.FileUtils;
import org.eclipse.babel.core.util.NameUtils;
import org.eclipse.babel.core.util.PDEUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;

/**
 * Manages all {@link MessagesBundleGroup}s. That is: <li>Hold map with projects
 * and their RBManager (1 RBManager per project)</li> <li>Hold up-to-date map
 * with resource bundles (= {@link MessagesBundleGroup})</li> <li>Hold
 * {@link IMessagesEditorListener}, which can be used to keep systems in sync</li>
 * <br>
 * <br>
 * 
 * @author Alexej Strelzow
 */
public final class RBManager {

    private static Map<IProject, RBManager> managerMap = new HashMap<IProject, RBManager>();

    /** <package>.<resourceBundleName> , IMessagesBundleGroup */
    private final Map<String, IMessagesBundleGroup> resourceBundles;

    private static RBManager INSTANCE;

    private final List<IMessagesEditorListener> editorListeners;

    private final List<IResourceDeltaListener> resourceListeners;

    private IProject project;

    private static final String TAPIJI_NATURE = "org.eclipse.babel.tapiji.tools.core.ui.nature";

    final static Logger logger = Logger.getLogger(RBManager.class.getName());

    private static IRefactoringService refactorService;

    private RBManager() {
        resourceBundles = new HashMap<String, IMessagesBundleGroup>();
        editorListeners = new ArrayList<IMessagesEditorListener>(3);
        resourceListeners = new ArrayList<IResourceDeltaListener>(2);
    }

    /**
     * @param resourceBundleId
     *            <package>.<resourceBundleName>
     * @return {@link IMessagesBundleGroup} if found, else <code>null</code>
     */
    public IMessagesBundleGroup getMessagesBundleGroup(String resourceBundleId) {
        if (!resourceBundles.containsKey(resourceBundleId)) {
            logger.log(Level.SEVERE,
                    "getMessagesBundleGroup with non-existing Id: "
                            + resourceBundleId);
            return null;
        } else {
            return resourceBundles.get(resourceBundleId);
        }
    }

    /**
     * @return All the names of the <code>resourceBundles</code> in the format:
     *         <projectName>/<resourceBundleId>
     */
    public List<String> getMessagesBundleGroupNames() {
        List<String> bundleGroupNames = new ArrayList<String>();

        for (String key : resourceBundles.keySet()) {
            bundleGroupNames.add(project.getName() + "/" + key);
        }
        return bundleGroupNames;
    }

    /**
     * @return All the {@link #getMessagesBundleGroupNames()} of all the
     *         projects.
     */
    public static List<String> getAllMessagesBundleGroupNames() {
        List<String> bundleGroupNames = new ArrayList<String>();

        for (IProject project : getAllSupportedProjects()) {
            RBManager manager = getInstance(project);
            for (String name : manager.getMessagesBundleGroupNames()) {
                if (!bundleGroupNames.contains(name)) {
                    bundleGroupNames.add(name);
                }
            }
        }
        return bundleGroupNames;
    }

    /**
     * Notification, that a {@link IMessagesBundleGroup} has been created and
     * needs to be managed by the {@link RBManager}.
     * 
     * @param bundleGroup
     *            The new {@link IMessagesBundleGroup}
     */
    public void notifyMessagesBundleGroupCreated(
            IMessagesBundleGroup bundleGroup) {
        if (resourceBundles.containsKey(bundleGroup.getResourceBundleId())) {
            IMessagesBundleGroup oldbundleGroup = resourceBundles
                    .get(bundleGroup.getResourceBundleId());

            // not the same object
            if (!equalHash(oldbundleGroup, bundleGroup)) {
                // we need to distinguish between 2 kinds of resources:
                // 1) Property-File
                // 2) Eclipse-Editor
                // When first 1) is used, and some operations where made, we
                // need to
                // sync 2) when it appears!
                boolean oldHasPropertiesStrategy = oldbundleGroup
                        .hasPropertiesFileGroupStrategy();
                boolean newHasPropertiesStrategy = bundleGroup
                        .hasPropertiesFileGroupStrategy();

                // in this case, the old one is only writing to the property
                // file, not the editor
                // we have to sync them and store the bundle with the editor as
                // resource
                if (oldHasPropertiesStrategy && !newHasPropertiesStrategy) {

                    syncBundles(bundleGroup, oldbundleGroup);
                    resourceBundles.put(bundleGroup.getResourceBundleId(),
                            bundleGroup);

                    logger.log(
                            Level.INFO,
                            "sync: " + bundleGroup.getResourceBundleId()
                                    + " with "
                                    + oldbundleGroup.getResourceBundleId());

                    oldbundleGroup.dispose();

                } else if ((oldHasPropertiesStrategy && newHasPropertiesStrategy)
                        || (!oldHasPropertiesStrategy && !newHasPropertiesStrategy)) {

                    // syncBundles(oldbundleGroup, bundleGroup); do not need
                    // that, because we take the new one
                    // and we do that, because otherwise we cache old
                    // Text-Editor instances, which we
                    // do not need -> read only phenomenon
                    resourceBundles.put(bundleGroup.getResourceBundleId(),
                            bundleGroup);

                    logger.log(
                            Level.INFO,
                            "replace: " + bundleGroup.getResourceBundleId()
                                    + " with "
                                    + oldbundleGroup.getResourceBundleId());

                    oldbundleGroup.dispose();
                } else {
                    // in this case our old resource has an EditorSite, but not
                    // the new one
                    logger.log(Level.INFO,
                            "dispose: " + bundleGroup.getResourceBundleId());

                    bundleGroup.dispose();
                }
            }
        } else {
            resourceBundles.put(bundleGroup.getResourceBundleId(), bundleGroup);

            logger.log(Level.INFO, "add: " + bundleGroup.getResourceBundleId());
        }
    }

    /**
     * Notification, that a {@link IMessagesBundleGroup} has been deleted!
     * 
     * @param bundleGroup
     *            The {@link IMessagesBundleGroup} to remove
     */
    public void notifyMessagesBundleGroupDeleted(
            IMessagesBundleGroup bundleGroup) {
        if (resourceBundles.containsKey(bundleGroup.getResourceBundleId())) {
            if (equalHash(
                    resourceBundles.get(bundleGroup.getResourceBundleId()),
                    bundleGroup)) {
                resourceBundles.remove(bundleGroup.getResourceBundleId());

                for (IResourceDeltaListener deltaListener : resourceListeners) {
                    deltaListener.onDelete(bundleGroup);
                }
            }
        }
    }

    /**
     * Notification, that a resource bundle (= {@link MessagesBundle}) have been
     * removed.
     * 
     * @param resourceBundle
     *            The removed {@link MessagesBundle}
     */
    public void notifyResourceRemoved(IResource resourceBundle) {
        String resourceBundleId = NameUtils.getResourceBundleId(resourceBundle);

        IMessagesBundleGroup bundleGroup = resourceBundles
                .get(resourceBundleId);

        if (bundleGroup != null) {
            Locale locale = NameUtils.getLocaleByName(
                    NameUtils.getResourceBundleName(resourceBundle),
                    resourceBundle.getName());
            IMessagesBundle messagesBundle = bundleGroup
                    .getMessagesBundle(locale);
            if (messagesBundle != null) {
                bundleGroup.removeMessagesBundle(messagesBundle);
            }

            for (IResourceDeltaListener deltaListener : resourceListeners) {
                deltaListener.onDelete(resourceBundleId, resourceBundle);
            }

            if (bundleGroup.getMessagesBundleCount() == 0) {
                notifyMessagesBundleGroupDeleted(bundleGroup);
            }
        }

        // TODO: maybe save and reinit the editor?

    }

    /**
     * Because BABEL-Builder does not work correctly (adds 1 x and removes 2 x
     * the SAME {@link MessagesBundleGroup}!)
     * 
     * @param oldBundleGroup
     *            {@link IMessagesBundleGroup}
     * @param newBundleGroup
     *            {@link IMessagesBundleGroup}
     * @return <code>true</code> if same {@link IMessagesBundleGroup}, else
     *         <code>false</code>
     */
    private boolean equalHash(IMessagesBundleGroup oldBundleGroup,
            IMessagesBundleGroup newBundleGroup) {
        return oldBundleGroup.hashCode() == newBundleGroup.hashCode();
    }

    /**
     * Has only one use case. If we worked with property-file as resource and
     * afterwards the messages editor pops open, we need to sync them, so that
     * the information of the property-file won't get lost.
     * 
     * @param oldBundleGroup
     *            The prior {@link IMessagesBundleGroup}
     * @param newBundleGroup
     *            The replacement
     */
    private void syncBundles(IMessagesBundleGroup oldBundleGroup,
            IMessagesBundleGroup newBundleGroup) {
        List<IMessagesBundle> bundlesToRemove = new ArrayList<IMessagesBundle>();
        List<IMessage> keysToRemove = new ArrayList<IMessage>();

        DirtyHack.setFireEnabled(false); // hebelt AbstractMessageModel aus
        // sonst m�ssten wir in setText von EclipsePropertiesEditorResource
        // ein
        // asyncExec zulassen

        for (IMessagesBundle newBundle : newBundleGroup.getMessagesBundles()) {
            IMessagesBundle oldBundle = oldBundleGroup
                    .getMessagesBundle(newBundle.getLocale());
            if (oldBundle == null) { // it's a new one
                oldBundleGroup.addMessagesBundle(newBundle.getLocale(),
                        newBundle);
            } else { // check keys
                for (IMessage newMsg : newBundle.getMessages()) {
                    if (oldBundle.getMessage(newMsg.getKey()) == null) {
                        // new entry, create new message
                        oldBundle.addMessage(new Message(newMsg.getKey(),
                                newMsg.getLocale()));
                    } else { // update old entries
                        IMessage oldMsg = oldBundle.getMessage(newMsg.getKey());
                        if (oldMsg == null) { // it's a new one
                            oldBundle.addMessage(newMsg);
                        } else { // check value
                            oldMsg.setComment(newMsg.getComment());
                            oldMsg.setText(newMsg.getValue());
                        }
                    }
                }
            }
        }

        // check keys
        for (IMessagesBundle oldBundle : oldBundleGroup.getMessagesBundles()) {
            IMessagesBundle newBundle = newBundleGroup
                    .getMessagesBundle(oldBundle.getLocale());
            if (newBundle == null) { // we have an old one
                bundlesToRemove.add(oldBundle);
            } else {
                for (IMessage oldMsg : oldBundle.getMessages()) {
                    if (newBundle.getMessage(oldMsg.getKey()) == null) {
                        keysToRemove.add(oldMsg);
                    }
                }
            }
        }

        for (IMessagesBundle bundle : bundlesToRemove) {
            oldBundleGroup.removeMessagesBundle(bundle);
        }

        for (IMessage msg : keysToRemove) {
            IMessagesBundle mb = oldBundleGroup.getMessagesBundle(msg
                    .getLocale());
            if (mb != null) {
                mb.removeMessage(msg.getKey());
            }
        }

        DirtyHack.setFireEnabled(true);

    }

    /**
     * If TapiJI needs to delete sth.
     * 
     * @param resourceBundleId
     *            The resourceBundleId
     */
    public void deleteMessagesBundleGroup(String resourceBundleId) {
        // TODO: Try to unify it some time
        if (resourceBundles.containsKey(resourceBundleId)) {
            resourceBundles.remove(resourceBundleId);
        } else {
            logger.log(Level.SEVERE,
                    "deleteMessagesBundleGroup with non-existing Id: "
                            + resourceBundleId);
        }
    }

    /**
     * @param resourceBundleId
     *            The resourceBundleId
     * @return <code>true</code> if the manager knows the
     *         {@link MessagesBundleGroup} with the id resourceBundleId
     */
    public boolean containsMessagesBundleGroup(String resourceBundleId) {
        return resourceBundles.containsKey(resourceBundleId);
    }

    /**
     * @param project
     *            The project, which is managed by the {@link RBManager}
     * @return The corresponding {@link RBManager} to the project
     */
    public static RBManager getInstance(IProject project) {
        // set host-project
        if (PDEUtils.isFragment(project)) {
            project = PDEUtils.getFragmentHost(project);
        }

        INSTANCE = managerMap.get(project);

        if (INSTANCE == null) {
            INSTANCE = new RBManager();
            INSTANCE.project = project;
            managerMap.put(project, INSTANCE);
            INSTANCE.detectResourceBundles();

            refactorService = getRefactoringService();
        }

        return INSTANCE;
    }

    /**
     * @param projectName
     *            The name of the project, which is managed by the
     *            {@link RBManager}
     * @return The corresponding {@link RBManager} to the project
     */
    public static RBManager getInstance(String projectName) {
        for (IProject project : getAllWorkspaceProjects(true)) {
            if (project.getName().equals(projectName)) {
                // check if the projectName is a fragment and return the manager
                // for the host
                if (PDEUtils.isFragment(project)) {
                    return getInstance(PDEUtils.getFragmentHost(project));
                } else {
                    return getInstance(project);
                }
            }
        }
        return null;
    }

    /**
     * @param ignoreNature
     *            <code>true</code> if the internationalization nature should be
     *            ignored, else <code>false</code>
     * @return A set of projects, which have the nature (ignoreNature == false)
     *         or not.
     */
    public static Set<IProject> getAllWorkspaceProjects(boolean ignoreNature) {
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
                .getProjects();
        Set<IProject> projs = new HashSet<IProject>();

        for (IProject p : projects) {
            try {
                if (p.isOpen() && (ignoreNature || p.hasNature(TAPIJI_NATURE))) {
                    projs.add(p);
                }
            } catch (CoreException e) {
                logger.log(Level.SEVERE,
                        "getAllWorkspaceProjects(...): hasNature failed!", e);
            }
        }
        return projs;
    }

    /**
     * @return All supported projects, those who have the correct nature.
     */
    public static Set<IProject> getAllSupportedProjects() {
        return getAllWorkspaceProjects(false);
    }

    /**
     * @param listener
     *            {@link IMessagesEditorListener} to add
     */
    public void addMessagesEditorListener(IMessagesEditorListener listener) {
        this.editorListeners.add(listener);
    }

    /**
     * @param listener
     *            {@link IMessagesEditorListener} to remove
     */
    public void removeMessagesEditorListener(IMessagesEditorListener listener) {
        this.editorListeners.remove(listener);
    }

    /**
     * @param listener
     *            {@link IResourceDeltaListener} to add
     */
    public void addResourceDeltaListener(IResourceDeltaListener listener) {
        this.resourceListeners.add(listener);
    }

    /**
     * @param listener
     *            {@link IResourceDeltaListener} to remove
     */
    public void removeResourceDeltaListener(IResourceDeltaListener listener) {
        this.resourceListeners.remove(listener);
    }

    /**
     * Fire: MessagesEditor has been saved
     */
    public void fireEditorSaved() {
        for (IMessagesEditorListener listener : this.editorListeners) {
            listener.onSave();
        }
        logger.log(Level.INFO, "fireEditorSaved");
    }

    /**
     * Fire: MessagesEditor has been modified
     */
    public void fireEditorChanged() {
        for (IMessagesEditorListener listener : this.editorListeners) {
            listener.onModify();
        }
        logger.log(Level.INFO, "fireEditorChanged");
    }

    /**
     * Fire: {@link IMessagesBundle} has been edited
     */
    public void fireResourceChanged(IMessagesBundle bundle) {
        for (IMessagesEditorListener listener : this.editorListeners) {
            listener.onResourceChanged(bundle);
            logger.log(Level.INFO, "fireResourceChanged"
                    + bundle.getResource().getResourceLocationLabel());
        }
    }

    /**
     * Detects all resource bundles, which we want to work with.
     */
    protected void detectResourceBundles() {
        try {
            project.accept(new ResourceBundleDetectionVisitor(this));

            IProject[] fragments = PDEUtils.lookupFragment(project);
            if (fragments != null) {
                for (IProject p : fragments) {
                    p.accept(new ResourceBundleDetectionVisitor(this));
                }

            }
        } catch (CoreException e) {
            logger.log(Level.SEVERE, "detectResourceBundles: accept failed!", e);
        }
    }

    // passive loading -> see detectResourceBundles
    /**
     * Invoked by {@link #detectResourceBundles()}.
     */
    public void addBundleResource(IResource resource) {
        // create it with MessagesBundleFactory or read from resource!
        // we can optimize that, now we create a bundle group for each bundle
        // we should create a bundle group only once!

        String resourceBundleId = NameUtils.getResourceBundleId(resource);
        if (!resourceBundles.containsKey(resourceBundleId)) {
            // if we do not have this condition, then you will be doomed with
            // resource out of syncs, because here we instantiate
            // PropertiesFileResources, which have an evil setText-Method
            MessagesBundleGroupFactory.createBundleGroup(resource);

            logger.log(Level.INFO, "addBundleResource (passive loading): "
                    + resource.getName());
        }
    }

    public void writeToFile(IMessagesBundleGroup bundleGroup) {
        for (IMessagesBundle bundle : bundleGroup.getMessagesBundles()) {
            FileUtils.writeToFile(bundle);
            fireResourceChanged(bundle);
        }
    }

    private static IRefactoringService getRefactoringService() {
        IExtensionPoint extp = Platform.getExtensionRegistry()
                .getExtensionPoint(
                        "org.eclipse.babel.core" + ".refactoringService");
        IConfigurationElement[] elements = extp.getConfigurationElements();

        if (elements.length != 0) {
            try {
                return (IRefactoringService) elements[0]
                        .createExecutableExtension("class");
            } catch (CoreException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static IRefactoringService getRefactorService() {
        return refactorService;
    }
}
