/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.resources.manager;

import com.android.SdkConstants;
import com.android.ide.common.resources.FrameworkResources;
import com.android.ide.common.resources.ResourceFile;
import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.ScanningContext;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IRawDeltaListener;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.ide.eclipse.adt.io.IFolderWrapper;
import com.android.io.FolderWrapper;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.IAndroidTarget;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * The ResourceManager tracks resources for all opened projects.
 * <p/>
 * It provide direct access to all the resources of a project as a {@link ProjectResources}
 * object that allows accessing the resources through their file representation or as Android
 * resources (similar to what is seen by an Android application).
 * <p/>
 * The ResourceManager automatically tracks file changes to update its internal representation
 * of the resources so that they are always up to date.
 * <p/>
 * It also gives access to a monitor that is more resource oriented than the
 * {@link GlobalProjectMonitor}.
 * This monitor will let you track resource changes by giving you direct access to
 * {@link ResourceFile}, or {@link ResourceFolder}.
 *
 * @see ProjectResources
 */
public final class ResourceManager {
    public final static boolean DEBUG = false;

    private final static ResourceManager sThis = new ResourceManager();

    /**
     * Map associating project resource with project objects.
     * <p/><b>All accesses must be inside a synchronized(mMap) block</b>, and do as a little as
     * possible and <b>not call out to other classes</b>.
     */
    private final Map<IProject, ProjectResources> mMap =
        new HashMap<IProject, ProjectResources>();

    /**
     * Interface to be notified of resource changes.
     *
     * @see ResourceManager#addListener(IResourceListener)
     * @see ResourceManager#removeListener(IResourceListener)
     */
    public interface IResourceListener {
        /**
         * Notification for resource file change.
         * @param project the project of the file.
         * @param file the {@link ResourceFile} representing the file.
         * @param eventType the type of event. See {@link IResourceDelta}.
         */
        void fileChanged(IProject project, ResourceFile file, int eventType);
        /**
         * Notification for resource folder change.
         * @param project the project of the file.
         * @param folder the {@link ResourceFolder} representing the folder.
         * @param eventType the type of event. See {@link IResourceDelta}.
         */
        void folderChanged(IProject project, ResourceFolder folder, int eventType);
    }

    private final ArrayList<IResourceListener> mListeners = new ArrayList<IResourceListener>();

    /**
     * Sets up the resource manager with the global project monitor.
     * @param monitor The global project monitor
     */
    public static void setup(GlobalProjectMonitor monitor) {
        monitor.addProjectListener(sThis.mProjectListener);
        monitor.addRawDeltaListener(sThis.mRawDeltaListener);

        CompiledResourcesMonitor.setupMonitor(monitor);
    }

    /**
     * Returns the singleton instance.
     */
    public static ResourceManager getInstance() {
        return sThis;
    }

    /**
     * Adds a new {@link IResourceListener} to be notified of resource changes.
     * @param listener the listener to be added.
     */
    public void addListener(IResourceListener listener) {
        synchronized (mListeners) {
            mListeners.add(listener);
        }
    }

    /**
     * Removes an {@link IResourceListener}, so that it's not notified of resource changes anymore.
     * @param listener the listener to be removed.
     */
    public void removeListener(IResourceListener listener) {
        synchronized (mListeners) {
            mListeners.remove(listener);
        }
    }

    /**
     * Returns the resources of a project.
     * @param project The project
     * @return a ProjectResources object
     */
    public ProjectResources getProjectResources(IProject project) {
        synchronized (mMap) {
            ProjectResources resources = mMap.get(project);

            if (resources == null) {
                resources = ProjectResources.create(project);
                mMap.put(project, resources);
            }

            return resources;
        }
    }

    /**
     * Update the resource repository with a delta
     *
     * @param delta the resource changed delta to process.
     * @param context a context object with state for the current update, such
     *            as a place to stash errors encountered
     */
    public void processDelta(IResourceDelta delta, IdeScanningContext context) {
        doProcessDelta(delta, context);

        // when a project is added to the workspace it is possible this is called before the
        // repo is actually created so this will return null.
        ResourceRepository repo = context.getRepository();
        if (repo != null) {
            repo.postUpdateCleanUp();
        }
    }

    /**
     * Update the resource repository with a delta
     *
     * @param delta the resource changed delta to process.
     * @param context a context object with state for the current update, such
     *            as a place to stash errors encountered
     */
    private void doProcessDelta(IResourceDelta delta, IdeScanningContext context) {
        // Skip over deltas that don't fit our mask
        int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED;
        int kind = delta.getKind();
        if ( (mask & kind) == 0) {
            return;
        }

        // Process this delta first as we need to make sure new folders are created before
        // we process their content
        IResource r = delta.getResource();
        int type = r.getType();

        if (type == IResource.FILE) {
            context.startScanning(r);
            updateFile((IFile)r, delta.getMarkerDeltas(), kind, context);
            context.finishScanning(r);
        } else if (type == IResource.FOLDER) {
            updateFolder((IFolder)r, kind, context);
        } // We only care about files and folders.
          // Project deltas are handled by our project listener

        // Now, process children recursively
        IResourceDelta[] children = delta.getAffectedChildren();
        for (IResourceDelta child : children)  {
            processDelta(child, context);
        }
    }

    /**
     * Update a resource folder that we know about
     * @param folder the folder that was updated
     * @param kind the delta type (added/removed/updated)
     */
    private void updateFolder(IFolder folder, int kind, IdeScanningContext context) {
        ProjectResources resources;

        final IProject project = folder.getProject();

        try {
            if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
                return;
            }
        } catch (CoreException e) {
            // can't get the project nature? return!
            return;
        }

        switch (kind) {
            case IResourceDelta.ADDED:
                // checks if the folder is under res.
                IPath path = folder.getFullPath();

                // the path will be project/res/<something>
                if (path.segmentCount() == 3) {
                    if (isInResFolder(path)) {
                        // get the project and its resource object.
                        synchronized (mMap) {
                            resources = mMap.get(project);

                            // if it doesn't exist, we create it.
                            if (resources == null) {
                                resources = ProjectResources.create(project);
                                mMap.put(project, resources);
                            }
                        }

                        ResourceFolder newFolder = resources.processFolder(
                                new IFolderWrapper(folder));
                        if (newFolder != null) {
                            notifyListenerOnFolderChange(project, newFolder, kind);
                        }
                    }
                }
                break;
            case IResourceDelta.CHANGED:
                // only call the listeners.
                synchronized (mMap) {
                    resources = mMap.get(folder.getProject());
                }
                if (resources != null) {
                    ResourceFolder resFolder = resources.getResourceFolder(folder);
                    if (resFolder != null) {
                        notifyListenerOnFolderChange(project, resFolder, kind);
                    }
                }
                break;
            case IResourceDelta.REMOVED:
                synchronized (mMap) {
                    resources = mMap.get(folder.getProject());
                }
                if (resources != null) {
                    // lets get the folder type
                    ResourceFolderType type = ResourceFolderType.getFolderType(
                            folder.getName());

                    context.startScanning(folder);
                    ResourceFolder removedFolder = resources.removeFolder(type,
                            new IFolderWrapper(folder), context);
                    context.finishScanning(folder);
                    if (removedFolder != null) {
                        notifyListenerOnFolderChange(project, removedFolder, kind);
                    }
                }
                break;
        }
    }

    /**
     * Called when a delta indicates that a file has changed. Depending on the
     * file being changed, and the type of change (ADDED, REMOVED, CHANGED), the
     * file change is processed to update the resource manager data.
     *
     * @param file The file that changed.
     * @param markerDeltas The marker deltas for the file.
     * @param kind The change kind. This is equivalent to
     *            {@link IResourceDelta#accept(IResourceDeltaVisitor)}
     * @param context a context object with state for the current update, such
     *            as a place to stash errors encountered
     */
    private void updateFile(IFile file, IMarkerDelta[] markerDeltas, int kind,
            ScanningContext context) {
        final IProject project = file.getProject();

        try {
            if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
                return;
            }
        } catch (CoreException e) {
            // can't get the project nature? return!
            return;
        }

        // get the project resources
        ProjectResources resources;
        synchronized (mMap) {
            resources = mMap.get(project);
        }

        if (resources == null) {
            return;
        }

        // checks if the file is under res/something or bin/res/something
        IPath path = file.getFullPath();

        if (path.segmentCount() == 4 || path.segmentCount() == 5) {
            if (isInResFolder(path)) {
                IContainer container = file.getParent();
                if (container instanceof IFolder) {

                    ResourceFolder folder = resources.getResourceFolder(
                            (IFolder)container);

                    // folder can be null as when the whole folder is deleted, the
                    // REMOVED event for the folder comes first. In this case, the
                    // folder will have taken care of things.
                    if (folder != null) {
                        ResourceFile resFile = folder.processFile(
                                new IFileWrapper(file),
                                ResourceHelper.getResourceDeltaKind(kind), context);
                        notifyListenerOnFileChange(project, resFile, kind);
                    }
                }
            }
        }
    }

    /**
     * Implementation of the {@link IProjectListener} as an internal class so that the methods
     * do not appear in the public API of {@link ResourceManager}.
     */
    private final IProjectListener mProjectListener = new IProjectListener() {
        @Override
        public void projectClosed(IProject project) {
            synchronized (mMap) {
                mMap.remove(project);
            }
        }

        @Override
        public void projectDeleted(IProject project) {
            synchronized (mMap) {
                mMap.remove(project);
            }
        }

        @Override
        public void projectOpened(IProject project) {
            createProject(project);
        }

        @Override
        public void projectOpenedWithWorkspace(IProject project) {
            createProject(project);
        }

        @Override
        public void allProjectsOpenedWithWorkspace() {
            // nothing to do.
        }

        @Override
        public void projectRenamed(IProject project, IPath from) {
            // renamed project get a delete/open event too, so this can be ignored.
        }
    };

    /**
     * Implementation of {@link IRawDeltaListener} as an internal class so that the methods
     * do not appear in the public API of {@link ResourceManager}. Delta processing can be
     * accessed through the {@link ResourceManager#visitDelta(IResourceDelta delta)} method.
     */
    private final IRawDeltaListener mRawDeltaListener = new IRawDeltaListener() {
        @Override
        public void visitDelta(IResourceDelta workspaceDelta) {
            // If we're auto-building, then PreCompilerBuilder will pass us deltas and
            // they will be processed as part of the build.
            if (isAutoBuilding()) {
                return;
            }

            // When *not* auto building, we need to process the deltas immediately on save,
            // even if the user is not building yet, such that for example resource ids
            // are updated in the resource repositories so rendering etc. can work for
            // those new ids.

            IResourceDelta[] projectDeltas = workspaceDelta.getAffectedChildren();
            for (IResourceDelta delta : projectDeltas) {
                if (delta.getResource() instanceof IProject) {
                    IProject project = (IProject) delta.getResource();

                    try {
                        if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
                            continue;
                        }
                    } catch (CoreException e) {
                        // only happens if the project is closed or doesn't exist.
                    }

                    IdeScanningContext context =
                            new IdeScanningContext(getProjectResources(project), project, true);

                    processDelta(delta, context);

                    Collection<IProject> projects = context.getAaptRequestedProjects();
                    if (projects != null) {
                        for (IProject p : projects) {
                            markAaptRequested(p);
                        }
                    }
                } else {
                    AdtPlugin.log(IStatus.WARNING, "Unexpected delta type: %1$s",
                            delta.getResource().toString());
                }
            }
        }
    };

    /**
     * Returns the {@link ResourceFolder} for the given file or <code>null</code> if none exists.
     */
    public ResourceFolder getResourceFolder(IFile file) {
        IContainer container = file.getParent();
        if (container.getType() == IResource.FOLDER) {
            IFolder parent = (IFolder)container;
            IProject project = file.getProject();

            ProjectResources resources = getProjectResources(project);
            if (resources != null) {
                return resources.getResourceFolder(parent);
            }
        }

        return null;
    }

    /**
     * Returns the {@link ResourceFolder} for the given folder or <code>null</code> if none exists.
     */
    public ResourceFolder getResourceFolder(IFolder folder) {
        IProject project = folder.getProject();

        ProjectResources resources = getProjectResources(project);
        if (resources != null) {
            return resources.getResourceFolder(folder);
        }

        return null;
    }

    /**
     * Loads and returns the resources for a given {@link IAndroidTarget}
     * @param androidTarget the target from which to load the framework resources
     */
    public ResourceRepository loadFrameworkResources(IAndroidTarget androidTarget) {
        String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);

        FolderWrapper frameworkRes = new FolderWrapper(osResourcesPath);
        if (frameworkRes.exists()) {
            FrameworkResources resources = new FrameworkResources(frameworkRes);

            resources.loadResources();
            resources.loadPublicResources(AdtPlugin.getDefault());
            return resources;
        }

        return null;
    }

    /**
     * Initial project parsing to gather resource info.
     * @param project
     */
    private void createProject(IProject project) {
        if (project.isOpen()) {
            synchronized (mMap) {
                ProjectResources projectResources = mMap.get(project);
                if (projectResources == null) {
                    projectResources = ProjectResources.create(project);
                    mMap.put(project, projectResources);
                }
            }
        }
    }


    /**
     * Returns true if the path is under /project/res/
     * @param path a workspace relative path
     * @return true if the path is under /project res/
     */
    private boolean isInResFolder(IPath path) {
        return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
    }

    private void notifyListenerOnFolderChange(IProject project, ResourceFolder folder,
            int eventType) {
        synchronized (mListeners) {
            for (IResourceListener listener : mListeners) {
                try {
                    listener.folderChanged(project, folder, eventType);
                } catch (Throwable t) {
                    AdtPlugin.log(t,
                            "Failed to execute ResourceManager.IResouceListener.folderChanged()"); //$NON-NLS-1$
                }
            }
        }
    }

    private void notifyListenerOnFileChange(IProject project, ResourceFile file, int eventType) {
        synchronized (mListeners) {
            for (IResourceListener listener : mListeners) {
                try {
                    listener.fileChanged(project, file, eventType);
                } catch (Throwable t) {
                    AdtPlugin.log(t,
                            "Failed to execute ResourceManager.IResouceListener.fileChanged()"); //$NON-NLS-1$
                }
            }
        }
    }

    /**
     * Private constructor to enforce singleton design.
     */
    private ResourceManager() {
    }

    // debug only
    @SuppressWarnings("unused")
    private String getKindString(int kind) {
        if (DEBUG) {
            switch (kind) {
                case IResourceDelta.ADDED: return "ADDED";
                case IResourceDelta.REMOVED: return "REMOVED";
                case IResourceDelta.CHANGED: return "CHANGED";
            }
        }

        return Integer.toString(kind);
    }

    /**
     * Returns true if the Project > Build Automatically option is turned on
     * (default).
     *
     * @return true if the Project > Build Automatically option is turned on
     *         (default).
     */
    public static boolean isAutoBuilding() {
        return ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding();
    }

    /** Qualified name for the per-project persistent property "needs aapt" */
    private final static QualifiedName NEED_AAPT = new QualifiedName(AdtPlugin.PLUGIN_ID,
            "aapt");//$NON-NLS-1$

    /**
     * Mark the given project, and any projects which depend on it as a library
     * project, as needing a full aapt build the next time the project is built.
     *
     * @param project the project to mark as needing aapt
     */
    public static void markAaptRequested(IProject project) {
        try {
            String needsAapt = Boolean.TRUE.toString();
            project.setPersistentProperty(NEED_AAPT, needsAapt);

            ProjectState state = Sdk.getProjectState(project);
            if (state.isLibrary()) {
                // For library projects also mark the dependent projects as needing full aapt
                for (ProjectState parent : state.getFullParentProjects()) {
                    IProject parentProject = parent.getProject();
                    // Mark the project, but only if it's open. Resource#setPersistentProperty
                    // only works on open projects.
                    if (parentProject.isOpen()) {
                        parentProject.setPersistentProperty(NEED_AAPT, needsAapt);
                    }
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e,  null);
        }
    }

    /**
     * Clear the "needs aapt" flag set by {@link #markAaptRequested(IProject)}.
     * This is usually called when a project is built. Note that this will only
     * clean the build flag on the given project, not on any downstream projects
     * that depend on this project as a library project.
     *
     * @param project the project to clear from the needs aapt list
     */
    public static void clearAaptRequest(IProject project) {
        try {
            project.setPersistentProperty(NEED_AAPT, null);
            // Note that even if this project is a library project, we -don't- clear
            // the aapt flags on the dependent projects since they may still depend
            // on other dirty projects. When they are built, they will issue their
            // own clear flag requests.
        } catch (CoreException e) {
            AdtPlugin.log(e,  null);
        }
    }

    /**
     * Returns whether the given project needs a full aapt build.
     *
     * @param project the project to check
     * @return true if the project needs a full aapt run
     */
    public static boolean isAaptRequested(IProject project) {
        try {
            String b = project.getPersistentProperty(NEED_AAPT);
            return b != null && Boolean.valueOf(b);
        } catch (CoreException e) {
            AdtPlugin.log(e,  null);
        }

        return false;
    }
}
