/*******************************************************************************
 * Copyright (c) 2005, 2016 IBM Corporation 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
 *
 *******************************************************************************/
package org.eclipse.dltk.ruby.core.tests.typeinference;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.evaluation.types.AmbiguousType;
import org.eclipse.dltk.evaluation.types.SimpleType;
import org.eclipse.dltk.evaluation.types.UnknownType;
import org.eclipse.dltk.ruby.core.tests.Activator;
import org.eclipse.dltk.ruby.typeinference.OffsetTargetedASTVisitor;
import org.eclipse.dltk.ruby.typeinference.RubyClassType;
import org.eclipse.dltk.ti.BasicContext;
import org.eclipse.dltk.ti.DLTKTypeInferenceEngine;
import org.eclipse.dltk.ti.ITypeInferencer;
import org.eclipse.dltk.ti.goals.ExpressionTypeGoal;
import org.eclipse.dltk.ti.types.IEvaluatedType;
import org.eclipse.dltk.ti.types.RecursionTypeCall;
import org.osgi.framework.Bundle;

import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;

public class TypeInferenceSuite extends TestSuite {

	@Override
	public void run(TestResult result) {
		TypeInferenceTest tests = new TypeInferenceTest("ruby selection tests");
		try {
			tests.setUpSuite();
		} catch (Throwable t) {
			result.addError(this, t);
			return;
		}
		try {
			super.run(result);
		} finally {
			try {
				tests.tearDownSuite();
			} catch (Throwable t) {
				t.printStackTrace();
			}
		}
	}

	public TypeInferenceSuite(Class<?> clazz, String testsDirectory) {
		super(clazz.getName());
		final Bundle bundle = Activator.getDefault().getBundle();
		Enumeration<String> entryPaths = bundle.getEntryPaths(testsDirectory);
		while (entryPaths.hasMoreElements()) {
			final String path = entryPaths.nextElement();
			URL entry = bundle.getEntry(path);
			try {
				entry.openStream().close();
			} catch (Exception e) {
				continue;
			}
			int pos = path.lastIndexOf('/');
			final String name = (pos >= 0 ? path.substring(pos + 1) : path);
			String x = path.substring(0, pos);
			pos = x.lastIndexOf('/');
			final String folder = (pos >= 0 ? x.substring(pos + 1) : x);
			addTest(new TestCase(name) {

				private Collection<IAssertion> assertions = new ArrayList<>();

				@Override
				public void setUp() {
				}

				@Override
				protected void runTest() throws Throwable {
					String content = loadContent(path);
					String[] lines = content.split("\n");
					int lineOffset = 0;
					for (int i = 0; i < lines.length; i++) {
						String line = lines[i].trim();
						int pos = line.indexOf("##");
						if (pos >= 0) {
							StringTokenizer tok = new StringTokenizer(line
									.substring(pos + 2));
							String test = tok.nextToken();
							if ("exit".equals(test)) {
								return;
							} else if ("localvar".equals(test)) {
								String varName = tok.nextToken();
								int namePos = lines[i].indexOf(varName);
								Assert.isLegal(namePos >= 0);
								namePos += lineOffset;
								String arrow = tok.nextToken();
								Assert.isLegal(arrow.equals("=>"));
								String correctClassRef = tok.nextToken();
								assertions.add(new VariableReturnTypeAssertion(
										varName, namePos, correctClassRef));
							} else if ("expr".equals(test)) {
								String expr = tok.nextToken();
								int namePos = lines[i].indexOf(expr);
								Assert.isLegal(namePos >= 0);
								namePos += lineOffset;
								String arrow = tok.nextToken();
								Assert.isLegal(arrow.equals("=>"));
								String correctClassRef = tok.nextToken();
								assertions.add(new ExpressionTypeAssertion(
										expr, namePos, correctClassRef));
							} else {
								// Assert.isLegal(false);
							}
						}
						lineOffset += lines[i].length() + 1;
					}

					if (assertions.size() == 0)
						return;

					ITypeInferencer inferencer = new DLTKTypeInferenceEngine();

					TypeInferenceTest tests = new TypeInferenceTest(
							"ruby selection tests");
					tests.executeTest(folder, name, inferencer, assertions);
				}

				class VariableReturnTypeAssertion implements IAssertion {

					private final String correctClassRef;

					// private final String varName;

					private final int namePos;

					public VariableReturnTypeAssertion(String varName,
							int namePos, String correctClassRef) {
						// this.varName = varName;
						this.namePos = namePos;
						this.correctClassRef = correctClassRef;
					}

					@Override
					public void check(ModuleDeclaration rootNode,
							ISourceModule cu, ITypeInferencer inferencer)
							throws Exception {
						final ASTNode[] result = new ASTNode[1];
						ASTVisitor visitor = new OffsetTargetedASTVisitor(
								namePos) {

							@Override
							protected boolean visitGeneralInteresting(ASTNode s) {
								if (s instanceof VariableReference)
									if (s.sourceStart() == namePos
											&& result[0] == null) {
										result[0] = s;
									}
								return true;
							}

						};
						rootNode.traverse(visitor);
						Assert.isLegal(result[0] != null);
						ExpressionTypeGoal goal = new ExpressionTypeGoal(
								new BasicContext(cu, rootNode), result[0]);
						IEvaluatedType type = inferencer.evaluateType(goal, -1);
						assertNotNull(type);

						assertEquals(correctClassRef, ((RubyClassType) type)
								.getModelKey());
					}

				}

				class ExpressionTypeAssertion implements IAssertion {

					private final String correctClassRef;

					// private final String expression;

					private final int namePos;

					public ExpressionTypeAssertion(String expression,
							int namePos, String correctClassRef) {
						// this.expression = expression;
						this.namePos = namePos;
						this.correctClassRef = correctClassRef;
					}

					@Override
					public void check(ModuleDeclaration rootNode,
							ISourceModule cu, ITypeInferencer inferencer)
							throws Exception {
						final ASTNode[] result = new ASTNode[1];
						ASTVisitor visitor = new OffsetTargetedASTVisitor(
								namePos) {

							@Override
							protected boolean visitGeneralInteresting(ASTNode s) {
								if (s != null && result[0] == null)
									if (s.sourceStart() == namePos) {
										result[0] = s;
									}
								return true;
							}

						};
						rootNode.traverse(visitor);
						if (result[0] == null)
							System.out
									.println("ExpressionTypeAssertion.check()");
						Assert.isLegal(result[0] != null);
						ExpressionTypeGoal goal = new ExpressionTypeGoal(
								new BasicContext(cu, rootNode), result[0]);
						IEvaluatedType type = inferencer.evaluateType(goal, -1);
						if (!correctClassRef.equals("recursion")) {
							if (type == null)
								throw new AssertionFailedError(
										"null type fetched, but "
												+ correctClassRef + " expected");
							assertNotNull(type);
							if (type instanceof SimpleType) {
								IEvaluatedType intrinsicType = getIntrinsicType(correctClassRef);
								assertEquals(intrinsicType, type);
							} else if (type instanceof RubyClassType) {
								RubyClassType rubyType = (RubyClassType) type;
								assertEquals(correctClassRef, rubyType
										.getModelKey());
							} else if (type instanceof AmbiguousType) {
								AmbiguousType ambiType = (AmbiguousType) type;
								Set<String> modelKeySet = new HashSet<>();
								IEvaluatedType[] possibleTypes = ambiType
										.getPossibleTypes();
								for (int cnt = 0, max = possibleTypes.length; cnt < max; cnt++) {
									if (possibleTypes[cnt] instanceof RubyClassType) {
										modelKeySet
												.add(((RubyClassType) possibleTypes[cnt])
														.getModelKey());
									}
								}
								assertTrue(modelKeySet
										.contains(correctClassRef));
							} else {
								fail("Unrecognized IEvaluatedType was inferred: "
										+ type.getClass().getName());
							}
						}
					}

				}

			});
		}
	}

	private String loadContent(String path) throws IOException {
		StringBuffer buffer = new StringBuffer();
		try (InputStream input = Activator.openResource(path);) {
			InputStreamReader reader = new InputStreamReader(input);
			BufferedReader br = new BufferedReader(reader);
			char[] data = new char[100 * 1024]; // tests shouldnt be more that
			// 100 kb
			int size = br.read(data);
			buffer.append(data, 0, size);
		}
		String content = buffer.toString();
		return content;
	}

	private static IEvaluatedType getIntrinsicType(String correctClassRef) {
		IEvaluatedType correctType;
		if ("recursion".equals(correctClassRef))
			correctType = RecursionTypeCall.INSTANCE;
		else if ("any".equals(correctClassRef))
			correctType = UnknownType.INSTANCE;
		// else if ("Fixnum".equals(correctClassRef))
		// correctType = new SimpleType(SimpleType.TYPE_NUMBER);
		// else if ("Str".equals(correctClassRef))
		// correctType = new SimpleType(SimpleType.TYPE_STRING);
		else
			correctType = null;
		return correctType;
	}
}
