/**
 * 
 */
package com.exxeta.iss.sonar.esql.check;

import java.util.Iterator;
import java.util.List;

import org.sonar.check.Rule;

import com.exxeta.iss.sonar.esql.api.tree.Tree;
import com.exxeta.iss.sonar.esql.api.tree.Tree.Kind;
import com.exxeta.iss.sonar.esql.api.visitors.SubscriptionVisitorCheck;
import com.exxeta.iss.sonar.esql.tree.impl.lexical.InternalSyntaxToken;
import com.google.common.collect.ImmutableList;

/**
 * This Java class is created to implement the logic for all binary operators
 * should be separated from their operands by spaces.
 * 
 * @author C50679
 *
 */
@Rule(key = "BinaryOperatorSepratedBySpace")
public class BinaryOperatorSepratedBySpaceCheck extends SubscriptionVisitorCheck {

	private static final String MESSAGE = "All binary operators should be separated from their operands by spaces.";
	private static final List<String> BINARY_OPERATOR = ImmutableList.of("=", ">", "<", "=<", ">=", "<>");

	@Override
	public void visitNode(Tree tree) {
		if (BINARY_OPERATOR.contains(((InternalSyntaxToken) tree).text())) {
			Iterator<Tree> childIterator = tree.parent().childrenStream().iterator();
			Tree prevChild = null;
			while (childIterator.hasNext()) {
				
				Tree child = childIterator.next();
				if (child == tree) {
					break;
				}
				prevChild = child;
			}
			Tree nextChild = null;
			if (childIterator.hasNext()) {
				nextChild = childIterator.next();
			}
			boolean noSpaceBefore = false;
			boolean noSpaceAfter = false;
			if (prevChild!=null && prevChild.lastToken().endLine() == ((InternalSyntaxToken) tree).endLine()) {
				if (prevChild.lastToken().endColumn() == ((InternalSyntaxToken) tree).column()){
					noSpaceBefore=true;
				}
			}
			if (nextChild!=null && ((InternalSyntaxToken) tree).endLine() == nextChild.firstToken().line()) {
				if (((InternalSyntaxToken) tree).endColumn()==nextChild.firstToken().column()){
					noSpaceAfter = true;
				}
			}
			if (noSpaceAfter || noSpaceBefore){
				addIssue(tree, MESSAGE);
			}
		}
		super.visitNode(tree);
	}

	@Override
	public List<Kind> nodesToVisit() {
		return ImmutableList.of(Tree.Kind.TOKEN);
	}

}

@@ -241,16 +241,80 @@
 .Kind;%0D%0A
+import com.exxeta.iss.sonar.esql.api.tree.lexical.SyntaxToken;%0D%0A
 import c
@@ -1292,20 +1292,16 @@
 t()) %7B%0D%0A
-%09%09%09%09
 %0D%0A%09%09%09%09Tr
@@ -1548,57 +1548,8 @@
 e = 
-false;%0D%0A%09%09%09boolean noSpaceAfter = false;%0D%0A%09%09%09if (
 prev
@@ -1557,103 +1557,41 @@
 hild
+ 
 !=
+ 
 null
- && prevChild.lastToken().endLine() == ((InternalSyntaxToken) tree).endLine()) %7B%0D%0A%09%09%09%09if 
+%0D%0A%09%09%09%09%09&& !isSpaceBetween
 (pre
@@ -1612,25 +1612,10 @@
 en()
-.endColumn() == (
+, 
 (Int
@@ -1641,67 +1641,37 @@
 ree)
-.column())%7B%0D%0A%09%09%09%09%09noSpaceBefore=true;%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%7D%0D%0A%09%09%09if (
+;%0D%0A%09%09%09boolean noSpaceAfter = 
 next
@@ -1679,102 +1679,41 @@
 hild
+ 
 !=
+ 
 null
- && ((InternalSyntaxToken) tree).endLine() == nextChild.firstToken().line()) %7B%0D%0A%09%09%09%09if (
+%0D%0A%09%09%09%09%09&& !isSpaceBetween
 ((In
@@ -1739,23 +1739,10 @@
 tree
-).endColumn()==
+, 
 next
@@ -1763,59 +1763,10 @@
 en()
-.column())%7B%0D%0A%09%09%09%09%09noSpaceAfter = true;%0D%0A%09%09%09%09%7D%0D%0A%09%09%09%7D
+);
 %0D%0A%09%09
@@ -1800,16 +1800,17 @@
 eBefore)
+ 
 %7B%0D%0A%09%09%09%09a
@@ -1873,24 +1873,247 @@
 ee);%0D%0A%09%7D%0D%0A%0D%0A
+%09private boolean isSpaceBetween(SyntaxToken firstTree, SyntaxToken secondTree) %7B%0D%0A%0D%0A%09%09if (firstTree.endLine() != secondTree.line()) %7B%0D%0A%09%09%09return true;%0D%0A%09%09%7D%0D%0A%0D%0A%09%09return firstTree.endColumn() != secondTree.column();%0D%0A%0D%0A%09%7D%0D%0A%0D%0A
 %09@Override%0D%0A

Extract isSpaceBetween method