/**
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */
package net.sourceforge.pmd.dcd;

import net.sourceforge.pmd.dcd.graph.ClassNode;
import net.sourceforge.pmd.dcd.graph.ConstructorNode;
import net.sourceforge.pmd.dcd.graph.FieldNode;
import net.sourceforge.pmd.dcd.graph.MemberNode;
import net.sourceforge.pmd.dcd.graph.MethodNode;
import net.sourceforge.pmd.dcd.graph.NodeVisitorAdapter;
import net.sourceforge.pmd.dcd.graph.UsageGraph;

/**
 * Dump a UsageGraph to System.out.
 */
public class DumpNodeVisitor extends NodeVisitorAdapter {

	@Override
	public Object visit(UsageGraph usageGraph, Object data) {
		System.out.println("----------------------------------------");
		super.visit(usageGraph, data);
		System.out.println("----------------------------------------");
		return data;
	}

	@Override
	public Object visit(ClassNode classNode, Object data) {
		System.out.println("Class: " + ClassLoaderUtil.fromInternalForm(classNode.getName()));
		return super.visit(classNode, data);
	}

	@Override
	public Object visitFields(ClassNode classNode, Object data) {
		System.out.println("\tFields (" + classNode.getFieldNodes().size() + "):");
		return super.visitFields(classNode, data);
	}

	@Override
	public Object visit(FieldNode fieldNode, Object data) {
		printMember(fieldNode);
		return super.visit(fieldNode, data);
	}

	@Override
	public Object visitConstructors(ClassNode classNode, Object data) {
		System.out.println("\tConstructors (" + classNode.getConstructorNodes().size() + "):");
		return super.visitConstructors(classNode, data);
	}

	@Override
	public Object visit(ConstructorNode constructorNode, Object data) {
		printMember(constructorNode);
		return super.visit(constructorNode, data);
	}

	@Override
	public Object visitMethods(ClassNode classNode, Object data) {
		System.out.println("\tMethods (" + classNode.getMethodNodes().size() + "):");
		return super.visitMethods(classNode, data);
	}

	@Override
	public Object visit(MethodNode methodNode, Object data) {
		printMember(methodNode);
		return super.visit(methodNode, data);
	}

	@Override
	public Object visitUses(MemberNode memberNode, Object data) {
		if (Boolean.TRUE == data && !memberNode.getUses().isEmpty()) {
			System.out.println("\t\t\tUses:");
		}
		return super.visitUses(memberNode, data);
	}

	@Override
	public Object visitUse(MemberNode use, Object data) {
		if (Boolean.TRUE == data) {
			System.out.println("\t\t\t\t" + use.toStringLong());
		}
		return super.visitUse(use, data);
	}

	@Override
	public Object visitUsers(MemberNode memberNode, Object data) {
		if (Boolean.TRUE == data && !memberNode.getUsers().isEmpty()) {
			System.out.println("\t\t\tUsers:");
		}
		return super.visitUsers(memberNode, data);
	}

	@Override
	public Object visitUser(MemberNode user, Object data) {
		if (Boolean.TRUE == data) {
			System.out.println("\t\t\t\t" + user.toStringLong());
		}
		return super.visitUser(user, data);
	}

	protected void printMember(MemberNode memberNode) {
		System.out.println("\t\t(" + memberNode.getUses().size() + ", " + memberNode.getUsers().size() + ") "
				+ memberNode.toStringLong());
	}
}
