package com.farpost.intellij.remotecall.utils;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.sun.jmx.remote.internal.ArrayQueue;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class FileNavigatorImpl implements FileNavigator {

	private final Logger log = Logger.getInstance(getClass().getName());

	@Override
	public void findAndNavigate(final String fileName, final int line) {
		ApplicationManager.getApplication().invokeLater(new Runnable() {
			public void run() {
				Map<Project, Collection<VirtualFile>> foundFilesInAllProjects = new HashMap<Project, Collection<VirtualFile>>();
				Project[] projects = ProjectManager.getInstance().getOpenProjects();

				for (Project project : projects) {
					foundFilesInAllProjects.put(project, FilenameIndex.getVirtualFilesByName(project, new File(fileName).getName(), GlobalSearchScope.allScope(project)));
				}

				ArrayQueue<String> pathElements = splitPath(fileName);
				String variableFileName = StringUtils.join(pathElements, File.separator);

				while (pathElements.size() > 0) {
					for (Project project : foundFilesInAllProjects.keySet()) {
						for (VirtualFile directFile : foundFilesInAllProjects.get(project)) {
							if (directFile.getPath().endsWith(variableFileName)) {
								log.info("Found file " + directFile.getName());
								navigate(project, directFile, line);
								return;
							}
						}
					}
					pathElements.remove(0);
					variableFileName = StringUtils.join(pathElements, File.separator);
				}
			}
		});
	}

	private ArrayQueue<String> splitPath(String filePath) {
		File file = new File(filePath);
		ArrayQueue<String> pathParts = new ArrayQueue<String>(128);
		pathParts.add(file.getName());
		String parentName;
		while ((parentName = file.getParent()) != null) {
			pathParts.add(parentName);
			file = file.getParentFile();
		}

		return pathParts;
	}

	private void navigate(Project project, VirtualFile file, int line) {
		final OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(project, file, line, 0);
		if (openFileDescriptor.canNavigate()) {
			log.info("Trying to navigate to " + file.getPath() + ":" + line);
			openFileDescriptor.navigate(true);
			WindowManager.getInstance().suggestParentWindow(project).toFront();
		} else {
			log.info("Cannot navigate");
		}
	}

}

@@ -495,55 +495,8 @@
 pe;%0A
-import com.sun.jmx.remote.internal.ArrayQueue;%0A
 impo
@@ -578,66 +578,9 @@
 til.
-Collection;%0Aimport java.util.HashMap;%0Aimport java.util.Map
+*
 ;%0A%0Ap
@@ -1276,24 +1276,19 @@
 %09%7D%0A%0A%09%09%09%09
-ArrayQue
+Deq
 ue%3CStrin
@@ -1808,16 +1808,12 @@
 nts.
-remove(0
+pop(
 );%0A%09
@@ -1913,24 +1913,19 @@
 private 
-ArrayQue
+Deq
 ue%3CStrin
@@ -1992,24 +1992,19 @@
 ath);%0A%09%09
-ArrayQue
+Deq
 ue%3CStrin
@@ -2031,11 +2031,11 @@
 rray
-Que
+Deq
 ue%3CS
@@ -2045,11 +2045,8 @@
 ng%3E(
-128
 );%0A%09
@@ -2056,19 +2056,20 @@
 thParts.
-add
+push
 (file.ge
@@ -2084,46 +2084,19 @@
 ;%0A%09%09
-String parentName;%0A%09%09while ((parentNam
+while ((fil
 e = 
@@ -2109,16 +2109,20 @@
 etParent
+File
 ()) != n
@@ -2145,55 +2145,28 @@
 rts.
-add(parentName);%0A%09%09%09file = file.getParentFil
+push(file.getNam
 e()
+)
 ;%0A%09%09

Fix directories list