package com.salto.test;

import java.io.PrintStream;
import java.util.List;

import uk.co.badgersinfoil.metaas.dom.ASAssignmentExpression;
import uk.co.badgersinfoil.metaas.dom.ASExpression;
import uk.co.badgersinfoil.metaas.dom.ASExpressionStatement;
import uk.co.badgersinfoil.metaas.dom.ASField;
import uk.co.badgersinfoil.metaas.dom.ASInvocationExpression;
import uk.co.badgersinfoil.metaas.dom.ASMethod;
import uk.co.badgersinfoil.metaas.impl.AbstractASMethodVisitor;

/**
 * @author remi
 * 
 */
public class DotASVisitor extends AbstractASMethodVisitor {

	private PrintStream printStream;

	private List<ASField> fields;

	private static String AFFECTATION_PATTERN = "(?sm).*[^\\w\\.](?:this.)?%s\\s*=\\s*([^;]*).*";

	private ASMethod method;

	private boolean currentMethodIncluded = false;

	public DotASVisitor(PrintStream printStream, List<ASField> fields) {
		this.printStream = printStream;
		this.fields = fields;

	}

	@Override
	public void visit(ASMethod method) {
		this.method = method;

	}

	@Override
	public void visit(ASExpressionStatement expressionStatement) {

		ASExpression expression = expressionStatement.getExpression();

		if (expression instanceof ASAssignmentExpression) {
			for (ASField field : fields) {

				String p = String.format(AFFECTATION_PATTERN, field.getName());

				if (("\n" + expressionStatement.getExpressionString()).matches(p)) {
					if (!currentMethodIncluded) {
						printStream.println("	__method__" + method.getName() + "[label=" + method.getName() + " shape=rect style=filled color=cadetblue3];");
						currentMethodIncluded = true;
					}
					printStream.println("	__method__" + method.getName() + " -> __field__" + field.getName() + ";");
				}
			}

		} else if (expression instanceof ASInvocationExpression) {

			// only local methods...
			if (!expressionStatement.getExpressionString().contains(".")) {

				if (!currentMethodIncluded) {
					printStream.println("	__method__" + method.getName() + "[label=" + method.getName() + " shape=rect style=filled color=cadetblue3];");
					currentMethodIncluded = true;
				}

				String invok = expressionStatement.getExpressionString();
				invok = invok.substring(0, invok.indexOf("("));
				printStream.println("	__method__" + method.getName() + " -> __method__" + invok + ";");
			}

		}

	}
}
