/*
 * Copyright (C) 2011 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.editors.layout.gle2;

import static com.android.SdkConstants.CLASS_VIEW;
import static com.android.SdkConstants.CLASS_VIEWGROUP;
import static com.android.SdkConstants.FN_FRAMEWORK_LIBRARY;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.utils.Pair;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.internal.core.ResolvedBinaryType;
import org.eclipse.jdt.internal.core.ResolvedSourceType;
import org.eclipse.swt.widgets.Display;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * The {@link CustomViewFinder} can look up the custom views and third party views
 * available for a given project.
 */
@SuppressWarnings("restriction") // JDT model access for custom-view class lookup
public class CustomViewFinder {
    /**
     * Qualified name for the per-project non-persistent property storing the
     * {@link CustomViewFinder} for this project
     */
    private final static QualifiedName CUSTOM_VIEW_FINDER = new QualifiedName(AdtPlugin.PLUGIN_ID,
            "viewfinder"); //$NON-NLS-1$

    /** Project that this view finder locates views for */
    private final IProject mProject;

    private final List<Listener> mListeners = new ArrayList<Listener>();

    private List<String> mCustomViews;
    private List<String> mThirdPartyViews;
    private boolean mRefreshing;

    /**
     * Constructs an {@link CustomViewFinder} for the given project. Don't use this method;
     * use the {@link #get} factory method instead.
     *
     * @param project project to create an {@link CustomViewFinder} for
     */
    private CustomViewFinder(IProject project) {
        mProject = project;
    }

    /**
     * Returns the {@link CustomViewFinder} for the given project
     *
     * @param project the project the finder is associated with
     * @return a {@CustomViewFinder} for the given project, never null
     */
    public static CustomViewFinder get(IProject project) {
        CustomViewFinder finder = null;
        try {
            finder = (CustomViewFinder) project.getSessionProperty(CUSTOM_VIEW_FINDER);
        } catch (CoreException e) {
            // Not a problem; we will just create a new one
        }

        if (finder == null) {
            finder = new CustomViewFinder(project);
            try {
                project.setSessionProperty(CUSTOM_VIEW_FINDER, finder);
            } catch (CoreException e) {
                AdtPlugin.log(e, "Can't store CustomViewFinder");
            }
        }

        return finder;
    }

    public void refresh() {
        refresh(null /*listener*/, true /* sync */);
    }

    public void refresh(final Listener listener) {
        refresh(listener, false /* sync */);
    }

    private void refresh(final Listener listener, boolean sync) {
        // Add this listener to the list of listeners which should be notified when the
        // search is done. (There could be more than one since multiple requests could
        // arrive for a slow search since the search is run in a different thread).
        if (listener != null) {
            synchronized (this) {
                mListeners.add(listener);
            }
        }
        synchronized (this) {
            if (listener != null) {
                mListeners.add(listener);
            }
            if (mRefreshing) {
                return;
            }
            mRefreshing = true;
        }

        FindViewsJob job = new FindViewsJob();
        job.schedule();
        if (sync) {
            try {
                job.join();
            } catch (InterruptedException e) {
                AdtPlugin.log(e, null);
            }
        }
    }

    public Collection<String> getCustomViews() {
        return mCustomViews == null ? null : Collections.unmodifiableCollection(mCustomViews);
    }

    public Collection<String> getThirdPartyViews() {
        return mThirdPartyViews == null
            ? null : Collections.unmodifiableCollection(mThirdPartyViews);
    }

    public Collection<String> getAllViews() {
        // Not yet initialized: return null
        if (mCustomViews == null) {
            return null;
        }
        List<String> all = new ArrayList<String>(mCustomViews.size() + mThirdPartyViews.size());
        all.addAll(mCustomViews);
        all.addAll(mThirdPartyViews);
        return all;
    }

    /**
     * Returns a pair of view lists - the custom views and the 3rd-party views.
     * This method performs no caching; it is the same as asking the custom view finder
     * to refresh itself and then waiting for the answer and returning it.
     *
     * @param project the Android project
     * @param layoutsOnly if true, only search for layouts
     * @return a pair of lists, the first containing custom views and the second
     *         containing 3rd party views
     */
    public static Pair<List<String>,List<String>> findViews(
            final IProject project, boolean layoutsOnly) {
        CustomViewFinder finder = get(project);

        return finder.findViews(layoutsOnly);
    }

    private Pair<List<String>,List<String>> findViews(final boolean layoutsOnly) {
        final Set<String> customViews = new HashSet<String>();
        final Set<String> thirdPartyViews = new HashSet<String>();

        ProjectState state = Sdk.getProjectState(mProject);
        final List<IProject> libraries = state != null
            ? state.getFullLibraryProjects() : Collections.<IProject>emptyList();

        SearchRequestor requestor = new SearchRequestor() {
            @Override
            public void acceptSearchMatch(SearchMatch match) throws CoreException {
                // Ignore matches in comments
                if (match.isInsideDocComment()) {
                    return;
                }

                Object element = match.getElement();
                if (element instanceof ResolvedBinaryType) {
                    // Third party view
                    ResolvedBinaryType type = (ResolvedBinaryType) element;
                    IPackageFragment fragment = type.getPackageFragment();
                    IPath path = fragment.getPath();
                    String last = path.lastSegment();
                    // Filter out android.jar stuff
                    if (last.equals(FN_FRAMEWORK_LIBRARY)) {
                        return;
                    }
                    if (!isValidView(type, layoutsOnly)) {
                        return;
                    }

                    IProject matchProject = match.getResource().getProject();
                    if (mProject == matchProject || libraries.contains(matchProject)) {
                        String fqn = type.getFullyQualifiedName();
                        thirdPartyViews.add(fqn);
                    }
                } else if (element instanceof ResolvedSourceType) {
                    // User custom view
                    IProject matchProject = match.getResource().getProject();
                    if (mProject == matchProject || libraries.contains(matchProject)) {
                        ResolvedSourceType type = (ResolvedSourceType) element;
                        if (!isValidView(type, layoutsOnly)) {
                            return;
                        }
                        String fqn = type.getFullyQualifiedName();
                        fqn = fqn.replace('$', '.');
                        customViews.add(fqn);
                    }
                }
            }
        };
        try {
            IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject);
            if (javaProject != null) {
                String className = layoutsOnly ? CLASS_VIEWGROUP : CLASS_VIEW;
                IType viewType = javaProject.findType(className);
                if (viewType != null) {
                    IJavaSearchScope scope = SearchEngine.createHierarchyScope(viewType);
                    SearchParticipant[] participants = new SearchParticipant[] {
                        SearchEngine.getDefaultSearchParticipant()
                    };
                    int matchRule = SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE;

                    SearchPattern pattern = SearchPattern.createPattern("*",
                            IJavaSearchConstants.CLASS, IJavaSearchConstants.IMPLEMENTORS,
                            matchRule);
                    SearchEngine engine = new SearchEngine();
                    engine.search(pattern, participants, scope, requestor,
                            new NullProgressMonitor());
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }


        List<String> custom = new ArrayList<String>(customViews);
        List<String> thirdParty = new ArrayList<String>(thirdPartyViews);

        if (!layoutsOnly) {
            // Update our cached answers (unless we were filtered on only layouts)
            mCustomViews = custom;
            mThirdPartyViews = thirdParty;
        }

        return Pair.of(custom, thirdParty);
    }

    /**
     * Determines whether the given member is a valid android.view.View to be added to the
     * list of custom views or third party views. It checks that the view is public and
     * not abstract for example.
     */
    private static boolean isValidView(IType type, boolean layoutsOnly)
            throws JavaModelException {
        // Skip anonymous classes
        if (type.isAnonymous()) {
            return false;
        }
        int flags = type.getFlags();
        if (Flags.isAbstract(flags) || !Flags.isPublic(flags)) {
            return false;
        }

        // TODO: if (layoutsOnly) perhaps try to filter out AdapterViews and other ViewGroups
        // not willing to accept children via XML

        // See if the class has one of the acceptable constructors
        // needed for XML instantiation:
        //    View(Context context)
        //    View(Context context, AttributeSet attrs)
        //    View(Context context, AttributeSet attrs, int defStyle)
        // We don't simply do three direct checks via type.getMethod() because the types
        // are not resolved, so we don't know for each parameter if we will get the
        // fully qualified or the unqualified class names.
        // Instead, iterate over the methods and look for a match.
        String typeName = type.getElementName();
        for (IMethod method : type.getMethods()) {
            // Only care about constructors
            if (!method.getElementName().equals(typeName)) {
                continue;
            }

            String[] parameterTypes = method.getParameterTypes();
            if (parameterTypes == null || parameterTypes.length < 1 || parameterTypes.length > 3) {
                continue;
            }

            String first = parameterTypes[0];
            // Look for the parameter type signatures -- produced by
            // JDT's Signature.createTypeSignature("Context", false /*isResolved*/);.
            // This is not a typo; they were copy/pasted from the actual parameter names
            // observed in the debugger examining these data structures.
            if (first.equals("QContext;")                                   //$NON-NLS-1$
                    || first.equals("Qandroid.content.Context;")) {         //$NON-NLS-1$
                if (parameterTypes.length == 1) {
                    return true;
                }
                String second = parameterTypes[1];
                if (second.equals("QAttributeSet;")                         //$NON-NLS-1$
                        || second.equals("Qandroid.util.AttributeSet;")) {  //$NON-NLS-1$
                    if (parameterTypes.length == 2) {
                        return true;
                    }
                    String third = parameterTypes[2];
                    if (third.equals("I")) {                                //$NON-NLS-1$
                        if (parameterTypes.length == 3) {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    /**
     * Interface implemented by clients of the {@link CustomViewFinder} to be notified
     * when a custom view search has completed. Will always be called on the SWT event
     * dispatch thread.
     */
    public interface Listener {
        void viewsUpdated(Collection<String> customViews, Collection<String> thirdPartyViews);
    }

    /**
     * Job for performing class search off the UI thread. This is marked as a system job
     * so that it won't show up in the progress monitor etc.
     */
    private class FindViewsJob extends Job {
        FindViewsJob() {
            super("Find Custom Views");
            setSystem(true);
        }
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            Pair<List<String>, List<String>> views = findViews(false);
            mCustomViews = views.getFirst();
            mThirdPartyViews = views.getSecond();

            // Notify listeners on SWT's UI thread
            Display.getDefault().asyncExec(new Runnable() {
                @Override
                public void run() {
                    Collection<String> customViews =
                        Collections.unmodifiableCollection(mCustomViews);
                    Collection<String> thirdPartyViews =
                        Collections.unmodifiableCollection(mThirdPartyViews);
                    synchronized (this) {
                        for (Listener l : mListeners) {
                            l.viewsUpdated(customViews, thirdPartyViews);
                        }
                        mListeners.clear();
                        mRefreshing = false;
                    }
                }
            });
            return Status.OK_STATUS;
        }
    }
}
