/*******************************************************************************
 * Copyright (c) 2008, 2016 xored software, Inc. 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:
 *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.ruby.formatter.tests;

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

import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.formatter.FormatterDocument;
import org.eclipse.dltk.formatter.IFormatterContainerNode;
import org.eclipse.dltk.formatter.IFormatterDocument;
import org.eclipse.dltk.formatter.IFormatterNode;
import org.eclipse.dltk.ruby.formatter.internal.RubyFormatterNodeBuilder;
import org.eclipse.dltk.ruby.formatter.internal.RubyParser;
import org.eclipse.dltk.ruby.formatter.internal.nodes.FormatterBlockWithBeginEndNode;
import org.eclipse.dltk.ui.formatter.FormatterException;
import org.jruby.ast.ArgumentNode;
import org.jruby.ast.ArrayNode;
import org.jruby.ast.ListNode;
import org.jruby.ast.Node;
import org.jruby.ast.ext.HeredocNode;
import org.jruby.ast.visitor.AbstractVisitor;
import org.jruby.evaluator.Instruction;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.parser.RubyParserResult;

public class ParserTest extends AbstractRubyFormatterTest {

	public void testEndKeyword() throws FormatterException {
		final String input = "class Test" + Util.LINE_SEPARATOR + "end"
				+ Util.LINE_SEPARATOR;
		final RubyParserResult result = RubyParser.parse(input);
		assertNotNull(result);
		final RubyFormatterNodeBuilder builder = new RubyFormatterNodeBuilder();
		final IFormatterDocument document = new FormatterDocument(input);
		final IFormatterContainerNode root = builder.build(result, document);
		assertNotNull(root);
		List<IFormatterNode> children = root.getChildren();
		assertEquals(2, children.size());
		final FormatterBlockWithBeginEndNode classNode = (FormatterBlockWithBeginEndNode) children
				.get(0);
		IFormatterNode endNode = classNode.getEnd();
		assertEquals(3, endNode.getEndOffset() - endNode.getStartOffset());
		assertEquals(input.indexOf("end"), endNode.getStartOffset());
	}

	public void testEmptyHereDoc() throws FormatterException {
		final String input = "a = <<THIS" + Util.LINE_SEPARATOR + "THIS"
				+ Util.LINE_SEPARATOR;
		RubyParserResult result = RubyParser.parse(input);
		assertNotNull(result);
	}

	public void testHereDocParser() throws FormatterException {
		final String id1 = "THIS";
		final String[] hereDoc1 = new String[] { "Line 1=a", "Line 2" };
		final String id2 = "THAT";
		final String[] hereDoc2 = new String[] { "Line 3=b", "Line 4" };
		String input = createInput(id1, hereDoc1, id2, hereDoc2);
		RubyParserResult result = RubyParser.parse(input);
		assertNotNull(result);
		final List<HeredocNode> heredocNodes = selectHeredocNodes(result);
		assertEquals(2, heredocNodes.size());
		final HeredocNode doc1 = heredocNodes.get(0);
		assertTrue(substring(input, doc1.getEndMarkerPosition()).indexOf(id1) >= 0);
		final String content1 = substring(input, doc1.getContentPosition());
		assertTrue(content1.indexOf(id1) < 0);
		assertTrue(content1.indexOf(hereDoc1[0]) >= 0);
		assertTrue(content1.indexOf(hereDoc1[1]) >= 0);
		final HeredocNode doc2 = heredocNodes.get(1);
		assertTrue(substring(input, doc2.getEndMarkerPosition()).indexOf(id2) >= 0);
		final String content2 = substring(input, doc2.getContentPosition());
		assertTrue(content2.indexOf(id2) < 0);
		assertTrue(content2.indexOf(hereDoc2[0]) >= 0);
		assertTrue(content2.indexOf(hereDoc2[1]) >= 0);
	}

	/**
	 * @param input
	 * @param position
	 */
	private String substring(String input, ISourcePosition position) {
		return input.substring(position.getStartOffset(),
				position.getEndOffset());
	}

	private String createInput(final String id1, final String[] hereDoc1,
			final String id2, final String[] hereDoc2) {
		List<String> lines = new ArrayList<String>();
		lines.add("def myfunc");
		lines.add("print <<\"" + id1 + "\", <<\"" + id2
				+ "\",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19");
		lines.addAll(Arrays.asList(hereDoc1));
		lines.add(id1);
		lines.addAll(Arrays.asList(hereDoc2));
		lines.add(id2);
		lines.add("end");
		String input = joinLines(lines);
		return input;
	}

	private List<HeredocNode> selectHeredocNodes(RubyParserResult result) {
		final List<HeredocNode> heredocNodes = new ArrayList<HeredocNode>();
		result.getAST().accept(new AbstractVisitor() {

			@Override
			protected Instruction visitNode(Node visited) {
				if (visited instanceof HeredocNode) {
					heredocNodes.add((HeredocNode) visited);
				}
				visitChildren(visited);
				return null;
			}

			private void visitChildren(Node visited) {
				List<Node> children = visited.childNodes();
				for (Iterator<Node> i = children.iterator(); i.hasNext();) {
					final Node child = i.next();
					visitChild(child);
				}
			}

			private void visitChild(final Node child) {
				if (child != null && isVisitable(child)) {
					child.accept(this);
				}
			}

			private boolean isVisitable(Node node) {
				return !(node instanceof ArgumentNode)
						&& node.getClass() != ListNode.class;
			}

		});
		return heredocNodes;
	}

	public void testRuby19hash() throws FormatterException {
		final String input = "hash = { one: 1, two: 2 }";
		RubyParserResult result = RubyParser.parse(input);
		assertNotNull(result);
		final List<Node> arrays = new ArrayList<Node>();
		result.getAST().accept(new AbstractVisitor() {
			@Override
			protected Instruction visitNode(Node visited) {
				if (visited instanceof ArrayNode) {
					arrays.add(visited);
				}
				visitChildren(visited);
				return null;
			}

			private void visitChildren(Node visited) {
				List<Node> children = visited.childNodes();
				for (Iterator<Node> i = children.iterator(); i.hasNext();) {
					final Node child = i.next();
					visitChild(child);
				}
			}

			private void visitChild(final Node child) {
				if (child != null) {
					child.accept(this);
				}
			}
		});
		assertEquals(1, arrays.size());
		final ArrayNode node = (ArrayNode) arrays.get(0);
		assertEquals(4, node.size());
	}

}
