/*******************************************************************************
 * Copyright (c) 2012, 2017 NumberFour AG and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     NumberFour AG - initial API and Implementation (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.core.tests;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.dltk.codeassist.ICompletionEngine;
import org.eclipse.dltk.codeassist.ISelectionEngine;
import org.eclipse.dltk.codeassist.ISelectionRequestor;
import org.eclipse.dltk.compiler.env.IModuleSource;
import org.eclipse.dltk.core.CompletionProposal;
import org.eclipse.dltk.core.CompletionRequestor;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.tests.util.StringList;
import org.eclipse.osgi.util.NLS;
import org.junit.Assert;

public class CodeAssistUtil {

	static abstract class Module<M> {
		final M module;

		public Module(M module) {
			this.module = module;
		}

		abstract String getSource();

		abstract String getName();

		abstract IModelElement[] codeSelect(int offset, int length)
				throws ModelException;

		abstract void codeComplete(int offset, CompletionRequestor requestor)
				throws ModelException;

	}

	private static class SourceModule extends Module<ISourceModule> {

		public SourceModule(ISourceModule module) {
			super(module);
		}

		@Override
		String getSource() {
			try {
				return module.getSource();
			} catch (ModelException e) {
				throw new IllegalStateException(e);
			}
		}

		@Override
		String getName() {
			return module.getElementName();
		}

		@Override
		IModelElement[] codeSelect(int offset, int length)
				throws ModelException {
			return module.codeSelect(offset, length);
		}

		@Override
		void codeComplete(int offset, CompletionRequestor requestor)
				throws ModelException {
			module.codeComplete(offset, requestor);
		}
	}

	private static class Source extends Module<IModuleSource> {
		public Source(IModuleSource source) {
			super(source);
		}

		@Override
		String getSource() {
			return module.getSourceContents();
		}

		@Override
		String getName() {
			return module.getFileName();
		}

		@Override
		IModelElement[] codeSelect(int offset, int length) {
			throw new UnsupportedOperationException();
		}

		@Override
		void codeComplete(int offset, CompletionRequestor requestor)
				throws ModelException {
			throw new UnsupportedOperationException();
		}
	}

	private final Module<?> module;
	private Integer offset;
	private int length;

	private CodeAssistUtil(Module<?> module) {
		this.module = module;
	}

	public static CodeAssistUtil on(IFile file) {
		return on(DLTKCore.createSourceModuleFrom(file));
	}

	public static CodeAssistUtil on(ISourceModule module) {
		return new CodeAssistUtil(new SourceModule(module));
	}

	public static CodeAssistUtil on(IModuleSource module) {
		return new CodeAssistUtil(new Source(module));
	}

	public CodeAssistUtil after(String marker) {
		return calculateOffset(marker, false, true);
	}

	public CodeAssistUtil afterLast(String marker) {
		return calculateOffset(marker, true, true);
	}

	public CodeAssistUtil before(String marker) {
		return calculateOffset(marker, false, false);
	}

	public CodeAssistUtil beforeLast(String marker) {
		return calculateOffset(marker, true, false);
	}

	private CodeAssistUtil calculateOffset(String marker, boolean last,
			boolean after) {
		final String text = module.getSource();
		final int offset = last ? text.lastIndexOf(marker)
				: text.indexOf(marker);
		Assert.assertTrue(NLS.bind("Pattern \"{0}\" not found in {1}", marker,
				module.getName()), offset != -1);
		this.offset = offset + (after ? marker.length() : 0);
		return this;
	}

	public CodeAssistUtil length(int length) {
		this.length = length;
		return this;
	}

	public int length() {
		return length;
	}

	public CodeAssistUtil offset(int offset) {
		this.offset = offset;
		return this;
	}

	public int offset() {
		return offset;
	}

	public IModelElement[] codeSelect() throws ModelException {
		return module.codeSelect(offset, length);
	}

	private IModuleSource getModuleSource() {
		return (IModuleSource) module.module;
	}

	/**
	 * Value class for completion proposals returned by
	 * {@link CodeAssistUtil#codeComplete()} methods.
	 */
	public class CodeCompletionResult {

		private final List<CompletionProposal> proposals;

		public CodeCompletionResult(List<CompletionProposal> proposals) {
			this.proposals = proposals;
		}

		public int size() {
			return proposals.size();
		}

		public CompletionProposal get(int index) {
			return proposals.get(index);
		}

		private boolean compareProposalNames(String[] names) {
			if (names.length != proposals.size()) {
				return false;
			}
			final CompletionProposal[] sorted = proposals
					.toArray(new CompletionProposal[proposals.size()]);
			Arrays.sort(sorted,
					(pr, pr1) -> pr.getName().compareTo(pr1.getName()));
			final String[] sortedNames = new String[names.length];
			System.arraycopy(names, 0, sortedNames, 0, names.length);
			Arrays.sort(sortedNames);
			for (int i = 0, size = proposals.size(); i < size; ++i) {
				if (!names[i].equals(proposals.get(i).getName())) {
					return false;
				}
			}
			return true;
		}

		private StringList exractProposalNames(boolean withKinds) {
			final StringList list = new StringList(proposals.size());
			for (int i = 0, size = proposals.size(); i < size; ++i) {
				final CompletionProposal proposal = proposals.get(i);
				String name = proposal.getName();
				if (withKinds && proposal
						.getKind() == CompletionProposal.METHOD_REF) {
					name += "()";
				}
				list.add(name);
			}
			return list;
		}

		public void assertEquals(String... expectedProposalNames) {
			if (!compareProposalNames(expectedProposalNames)) {
				Assert.assertEquals(
						new StringList(expectedProposalNames).sort().toString(),
						exractProposalNames(false).sort().toString());
			}
		}

		/**
		 * Finds the proposal with the specified name or throws exception if no
		 * such proposal found.
		 */
		public CompletionProposal get(String name)
				throws IllegalArgumentException {
			for (CompletionProposal proposal : proposals) {
				if (name.equals(proposal.getName())) {
					return proposal;
				}
			}
			throw new IllegalArgumentException(
					NLS.bind("\"{0}\" completion proposal not found", name));
		}

		/**
		 * Finds the proposal with the specified kind and name or throws
		 * exception if no such proposal found.
		 */
		public CompletionProposal get(int kind, String name)
				throws IllegalArgumentException {
			for (CompletionProposal proposal : proposals) {
				if (kind == proposal.getKind()
						&& name.equals(proposal.getName())) {
					return proposal;
				}
			}
			throw new IllegalArgumentException(NLS.bind(
					"\"{0}:{1}\" completion proposal not found", kind, name));
		}
	}

	public CodeCompletionResult codeComplete(ICompletionEngine engine) {
		final List<CompletionProposal> proposals = new ArrayList<>();
		engine.setRequestor(new TestCompletionRequestor(proposals));
		engine.complete(getModuleSource(), offset(), 0);
		return new CodeCompletionResult(proposals);
	}

	/**
	 * Performs code completion in this source module.
	 */
	public CodeCompletionResult codeComplete() throws ModelException {
		final List<CompletionProposal> proposals = new ArrayList<>();
		module.codeComplete(offset(), new TestCompletionRequestor(proposals));
		return new CodeCompletionResult(proposals);
	}

	public Object[] codeSelectAll(ISelectionEngine engine) {
		final List<Object> elements = new ArrayList<>();
		engine.setRequestor(new ISelectionRequestor() {
			@Override
			public void acceptModelElement(IModelElement element) {
				elements.add(element);
			}

			@Override
			public void acceptForeignElement(Object element) {
				elements.add(element);
			}

			@Override
			public void acceptElement(Object element, ISourceRange range) {
				elements.add(element);
			}
		});
		final IModelElement[] result = engine.select(getModuleSource(), offset,
				offset);
		if (result != null) {
			Collections.addAll(elements, result);
		}
		return elements.toArray();
	}

	public IModelElement[] codeSelect(ISelectionEngine engine) {
		final List<IModelElement> elements = new ArrayList<>();
		engine.setRequestor(new ISelectionRequestor() {

			@Override
			public void acceptModelElement(IModelElement element) {
				elements.add(element);
			}

			@Override
			public void acceptForeignElement(Object element) {
				if (element instanceof IModelElement) {
					elements.add((IModelElement) element);
				}
			}

			@Override
			public void acceptElement(Object element, ISourceRange range) {
				acceptForeignElement(element);
			}
		});
		final IModelElement[] result = engine.select(getModuleSource(), offset,
				offset);
		if (result != null) {
			Collections.addAll(elements, result);
		}
		return elements.toArray(new IModelElement[elements.size()]);
	}

}
