/*******************************************************************************
 * Copyright (c) 2015 QNX Software Systems and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.cdt.internal.qt.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.eclipse.cdt.qt.core.IQMLAnalyzer;
import org.eclipse.cdt.qt.core.QMLTernCompletion;
import org.eclipse.cdt.qt.core.qmljs.IQmlASTNode;

@SuppressWarnings("nls")
public class QMLAnalyzer implements IQMLAnalyzer {

	private QMLModuleResolver moduleResolver;
	private ScriptEngine engine;
	private Boolean supported;
	private Invocable invoke;
	private Object tern;

	@Override
	public void load() throws ScriptException, IOException, NoSuchMethodException {
		moduleResolver = new QMLModuleResolver(this);
		engine = new ScriptEngineManager().getEngineByName("nashorn");
		if (engine == null) {
			synchronized (this) {
				supported = false;
				notifyAll();
			}
			throw new ScriptException(
					"Nashorn script engine is not available in Java 15 and above. The QML Analyzer is not supported.");
		}
		invoke = (Invocable) engine;

		loadDep("/tern-qml/node_modules/acorn/dist/acorn.js");
		loadDep("/tern-qml/node_modules/acorn/dist/acorn_loose.js");
		loadDep("/tern-qml/node_modules/acorn/dist/walk.js");

		loadDep("/tern-qml/node_modules/tern/lib/signal.js");
		loadDep("/tern-qml/node_modules/tern/lib/tern.js");
		loadDep("/tern-qml/node_modules/tern/lib/def.js");
		loadDep("/tern-qml/node_modules/tern/lib/comment.js");
		loadDep("/tern-qml/node_modules/tern/lib/infer.js");

		load("/acorn-qml/inject.js");
		load("/acorn-qml/index.js");
		load("/acorn-qml/loose/inject.js");
		load("/acorn-qml/loose/index.js");
		load("/acorn-qml/walk/index.js");

		load("/tern-qml/qml.js");
		load("/tern-qml/qml-nsh.js");

		Bindings options = (Bindings) engine.eval("new Object()");
		options.put("ecmaVersion", 5);

		Bindings plugins = (Bindings) engine.eval("new Object()");
		plugins.put("qml", true);
		options.put("plugins", plugins);

		Bindings defs = (Bindings) engine.eval("new Array()");
		load("/tern-qml/ecma5-defs.js");
		invoke.invokeMethod(defs, "push", engine.get("ecma5defs"));
		options.put("defs", defs);

		ResolveDirectory resolveDirectory = (file, pathString) -> {
			String filename = (String) file.get("name");
			String fileDirectory = new File(filename).getParent();
			if (fileDirectory == null) {
				fileDirectory = "";
			}
			if (pathString == null) {
				return fixPathString(fileDirectory);
			}
			Path fileDirectoryPath = Paths.get(fileDirectory);
			Path path = Paths.get(pathString);
			if (!path.isAbsolute()) {
				path = fileDirectoryPath.toAbsolutePath().resolve(path);
			}
			return fixPathString(path.normalize().toString());
		};
		options.put("resolveDirectory", invoke.invokeFunction("resolveDirectory", resolveDirectory));
		options.put("resolveModule", invoke.invokeFunction("resolveModule", moduleResolver));

		synchronized (this) {
			tern = invoke.invokeFunction("newTernServer", options);
			supported = tern != null;
			notifyAll();
		}
	}

	@FunctionalInterface
	public interface ResolveDirectory {
		public String resolveDirectory(Bindings file, String path);
	}

	private Object load(String file) throws ScriptException, IOException {
		URL scriptURL = Activator.getDefault().getBundle().getEntry(file);
		if (scriptURL == null) {
			throw new FileNotFoundException(file);
		}
		engine.getContext().setAttribute(ScriptEngine.FILENAME, file, ScriptContext.ENGINE_SCOPE);
		return engine.eval(new BufferedReader(new InputStreamReader(scriptURL.openStream(), StandardCharsets.UTF_8)));
	}

	private Object loadDep(String file) throws ScriptException, IOException {
		try {
			return load(file);
		} catch (FileNotFoundException e) {
			return load(file.replace("/tern-qml/node_modules/", "/tern-qml/dist/"));
		}
	}

	@Override
	public boolean isSupported() {
		synchronized (this) {
			while (supported == null) {
				try {
					wait();
				} catch (InterruptedException e) {
					Activator.log(e);
					return false;
				}
			}
			return supported;
		}
	}

	private void waitUntilLoaded() throws ScriptException {
		if (!isSupported()) {
			throw new ScriptException(
					"Nashorn script engine is not available in Java 15 and above. The QML Analyzer is not supported.");
		}
	}

	@FunctionalInterface
	public interface RequestCallback {
		void callback(Object err, Object data);
	}

	private String fixPathString(String fileName) {
		fileName = fileName.replaceAll("\\\\", "/");
		if (fileName.startsWith("/")) {
			fileName = fileName.substring(1);
		}
		return fileName;
	}

	@Override
	public void addFile(String fileName, String code) throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		invoke.invokeMethod(tern, "addFile", fixPathString(fileName), code);
	}

	@Override
	public void deleteFile(String fileName) throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		invoke.invokeMethod(tern, "delFile", fixPathString(fileName));
	}

	private static class ASTCallback implements RequestCallback {
		private IQmlASTNode ast;

		@Override
		public void callback(Object err, Object data) {
			if (err != null) {
				throw new RuntimeException(err.toString());
			} else {
				try {
					ast = QmlASTNodeHandler.createQmlASTProxy((Bindings) ((Bindings) data).get("ast"));
				} catch (Throwable e) {
					throw new RuntimeException(e);
				}
			}
		}

		public IQmlASTNode getAST() {
			return ast;
		}
	}

	@Override
	public IQmlASTNode parseFile(String fileName, String text) throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		fileName = fixPathString(fileName);

		Bindings query = engine.createBindings();
		query.put("type", "parseFile");
		query.put("file", fileName);
		Bindings request = engine.createBindings();
		request.put("query", query);

		if (text != null) {
			Bindings file = engine.createBindings();
			file.put("type", "full");
			file.put("name", fileName);
			file.put("text", text);
			Bindings files = (Bindings) engine.eval("new Array()");
			invoke.invokeMethod(files, "push", file);
			request.put("files", files);
		}

		ASTCallback callback = new ASTCallback();
		invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));
		return callback.getAST();
	}

	@Override
	public IQmlASTNode parseString(String text) throws NoSuchMethodException, ScriptException {
		return parseString(text, "qml", false, false);
	}

	@Override
	public IQmlASTNode parseString(String text, String mode, boolean locations, boolean ranges)
			throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		Bindings options = engine.createBindings();
		options.put("mode", mode);
		options.put("locations", locations);
		options.put("ranges", ranges);

		ASTCallback callback = new ASTCallback();
		invoke.invokeMethod(tern, "parseString", text, options, invoke.invokeFunction("requestCallback", callback));
		return callback.getAST();
	}

	protected <T> T[] toJavaArray(Bindings binding, Class<T[]> clazz) throws NoSuchMethodException, ScriptException {
		return clazz.cast(invoke.invokeMethod(engine.get("Java"), "to", binding,
				clazz.getCanonicalName() + (clazz.isArray() ? "" : "[]")));
	}

	@Override
	public Collection<QMLTernCompletion> getCompletions(String fileName, String text, int pos)
			throws NoSuchMethodException, ScriptException {
		return getCompletions(fileName, text, pos, true);
	}

	@Override
	public Collection<QMLTernCompletion> getCompletions(String fileName, String text, int pos, boolean includeKeywords)
			throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		fileName = fixPathString(fileName);

		Bindings query = engine.createBindings();
		query.put("type", "completions");
		query.put("lineCharPositions", true);
		query.put("file", fileName);
		query.put("end", pos);
		query.put("types", true);
		query.put("docs", false);
		query.put("urls", false);
		query.put("origins", true);
		query.put("filter", true);
		query.put("caseInsensitive", true);
		query.put("guess", false);
		query.put("sort", true);
		query.put("expandWordForward", false);
		query.put("includeKeywords", includeKeywords);

		Bindings request = engine.createBindings();
		request.put("query", query);
		if (text != null) {
			Bindings file = engine.createBindings();
			file.put("type", "full");
			file.put("name", fileName);
			file.put("text", text);
			Bindings files = (Bindings) engine.eval("new Array()");
			invoke.invokeMethod(files, "push", file);
			request.put("files", files);
		}

		List<QMLTernCompletion> completions = new ArrayList<>();

		RequestCallback callback = (err, data) -> {
			if (err != null) {
				throw new RuntimeException(err.toString());
			} else {
				try {
					Bindings comps = (Bindings) ((Bindings) data).get("completions");
					for (Bindings completion : toJavaArray(comps, Bindings[].class)) {
						completions.add(new QMLTernCompletion((String) completion.get("name"),
								(String) completion.get("type"), (String) completion.get("origin")));
					}
				} catch (Throwable e) {
					throw new RuntimeException(e);
				}
			}
		};

		invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));

		return completions;
	}

	@Override
	public List<Bindings> getDefinition(String identifier, String fileName, String text, int pos)
			throws NoSuchMethodException, ScriptException {
		waitUntilLoaded();
		fileName = fixPathString(fileName);

		Bindings query = engine.createBindings();
		query.put("type", "definition");
		query.put("file", fileName);
		query.put("end", pos);
		query.put("types", true);
		query.put("docs", false);
		query.put("urls", false);
		query.put("origins", true);
		query.put("caseInsensitive", true);
		query.put("lineCharPositions", true);
		query.put("expandWordForward", false);
		query.put("includeKeywords", true);
		query.put("guess", false);
		Bindings request = engine.createBindings();
		request.put("query", query);
		if (text != null) {
			Bindings file = engine.createBindings();
			file.put("type", "full");
			file.put("name", fileName);
			file.put("text", text);
			Bindings files = (Bindings) engine.eval("new Array()");
			invoke.invokeMethod(files, "push", file);
			request.put("files", files);
		}

		List<Bindings> definitions = new ArrayList<>();

		RequestCallback callback = (err, data) -> {
			if (err != null) {
				throw new RuntimeException(err.toString());
			} else {
				definitions.add((Bindings) data);
			}
		};

		invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));
		return definitions;
	}

}
