/*
 * Copyright (C) 2010 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;

import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener;
import com.android.ide.eclipse.ddms.IDebuggerConnector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Implementation of the com.android.ide.ddms.debuggerConnector extension point.
 */
public class DebuggerConnector implements IDebuggerConnector {
    private WorkspaceAppCache mWorkspaceAppCache;

    public DebuggerConnector() {
        mWorkspaceAppCache = new WorkspaceAppCache();
        GlobalProjectMonitor.getMonitor().addProjectListener(mWorkspaceAppCache);
    }

    @Override
    public boolean connectDebugger(String appName, int appPort, int selectedPort) {
        // search for an android project matching the process name
        IProject project = ProjectHelper.findAndroidProjectByAppName(appName);
        if (project != null) {
            AndroidLaunchController.debugRunningApp(project, appPort);
            return true;
        }

        return false;
    }

    /** {@inheritDoc} */
    @Override
    public boolean isWorkspaceApp(String appName) {
        return mWorkspaceAppCache.isWorkspaceApp(appName);
    }

    /**
     * A cache of Android application name to workspace project name mappings.
     * Users can query whether an application is present in the workspace using
     * {@link #isWorkspaceApp(String)}. The cache listens to workspace changes
     * (project open/close/delete etc), and keeps its internal mappings up-to-date.<br>
     * This class is designed with the following assumptions:
     * <ul>
     *   <li> There are a significant number of calls to {@link #isWorkspaceApp(String)}, with
     *        a large number of possible application names as arguments. </li>
     *   <li> The number of projects actually present in the workspace, and the
     *        number of user initiated project changes (project open/close/delete/rename) are both
     *        relatively small. </li>
     * </ul>
     */
    static class WorkspaceAppCache implements IProjectListener {
        /** Apps known to be not in the workspace. */
        private Set<String> mAppsNotInWorkspace;

        /** Mapping of application name to project name for apps present in the workspace. */
        private Map<String, String> mAppsInWorkspace;

        public WorkspaceAppCache() {
            mAppsNotInWorkspace = new HashSet<String>();
            mAppsInWorkspace = new HashMap<String, String>();
        }

        public boolean isWorkspaceApp(String appName) {
            if (mAppsNotInWorkspace.contains(appName)) {
                return false;
            }

            String projectName = mAppsInWorkspace.get(appName);
            if (projectName == null) {
                IProject p = ProjectHelper.findAndroidProjectByAppName(appName);
                if (p == null) {
                    mAppsNotInWorkspace.add(appName);
                } else {
                    projectName = p.getName();
                    mAppsInWorkspace.put(appName, projectName);
                }
            }
            return projectName != null;
        }

        /** {@inheritDoc} */
        @Override
        public void projectRenamed(IProject project, IPath from) {
            // when a project is renamed, ideally we should just update the current
            // known mapping of app name -> project name. However, the projectRenamed
            // callback is called only after projectDeleted() and projectOpened() are called,
            // so there is really nothing we can do here..
        }

        /** {@inheritDoc} */
        @Override
        public void projectOpenedWithWorkspace(IProject project) {
            // don't do anything as the cache is lazily initialized
        }

        @Override
        public void allProjectsOpenedWithWorkspace() {
            // don't do anything as the cache is lazily initialized
        }

        /** {@inheritDoc} */
        @Override
        public void projectOpened(IProject project) {
            // A newly opened project could contribute some Android application.
            // So we invalidate the set of apps that are known to be not in the workspace, as
            // that set could be out of date now.
            mAppsNotInWorkspace.clear();
        }

        /** {@inheritDoc} */
        @Override
        public void projectDeleted(IProject project) {
            // Deletion is effectively the same as closing
            projectClosed(project);
        }

        /** {@inheritDoc} */
        @Override
        public void projectClosed(IProject project) {
            // When a project is closed, remove all mappings contributed by the project.
            Map<String, String> updatedCache = new HashMap<String, String>();

            String name = project.getName();
            for (Entry<String, String> e : mAppsInWorkspace.entrySet()) {
                if (!e.getValue().equals(name)) {
                    updatedCache.put(e.getKey(), e.getValue());
                }
            }

            mAppsInWorkspace = updatedCache;
        }
    }
}
