package edu.claflin.finder.algo.clustering.struct.leading_eigenvector_struct;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import edu.claflin.finder.io.graph.SimpleGraphIO;
import edu.claflin.finder.logic.Graph;
import edu.claflin.finder.logic.Node;

// Standalone tester class for LeadingEigenvectorAlgorithm. It has a bunch of static utility 
// functions used for debugging purposes which made printing info in LeadingEigenvectorAlgorithm.java,
// although all references were removed once the code was fully tested.

public class Tester
{
	private static Graph graph;
	
	public static void main(String[] args) throws IOException
	{	
		String fname = "samuel_small_test_text.txt";
		SimpleGraphIO sgio = new SimpleGraphIO();
		Graph g = sgio.parseGraph(new File("./Test Graphs/" + fname), true);
		graph = g;
		
		LeadingEigenvectorCaller leigenc = new LeadingEigenvectorCaller(g);
		System.out.println(Tester.communitiesToString(leigenc.getCommunities()));
	}
	
	public static String arrayToString(int[] array) {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		
		for(int i = 0; i < array.length; i++) {
			sb.append(String.format("%2d", array[i]) + ", ");
		}
		
		sb.delete(sb.length() - 2, sb.length());
		sb.append("]");
		
		return sb.toString();
	}
	
	public static String arrayToString(double[] array) {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		
		for(int i = 0; i < array.length; i++) {
			sb.append(String.format("%2.2f", array[i]) + ", ");
		}
		
		sb.delete(sb.length() - 2, sb.length());
		sb.append("]");
		
		return sb.toString();
	}
	
	public static String matrixToString(double[][] matrix) {
		StringBuilder sb = new StringBuilder();
		sb.append("\n|");
		
		for(int i = 0; i < matrix.length; i++) {
			for(int j = 0; j < matrix[i].length; j++) {
				sb.append(String.format("%5.2f", matrix[i][j]) + "|");
			}
			sb.append("\n|");
		}
		
		sb.deleteCharAt(sb.length() - 1);
		
		return sb.toString();
	}
	
	public static String communitiesToString(HashMap<Integer, List<Node>> communities) {
		StringBuilder sb = new StringBuilder();
		
		for(Integer key : communities.keySet()) {
			sb.append("Community " + key + ": {");
			
			for(Node node : communities.get(key)) {
				sb.append(node.getIdentifier() + ", ");
			}
			
			sb.delete(sb.length() - 2, sb.length());
			sb.append("}, Nodes: ");
			sb.append(communities.get(key).size());
			
			sb.append(", Edges: ");
			sb.append(graph.getEdgesBack(communities.get(key)).size() + "\n");
		}
		
		return sb.toString();
	}
	
	public static String groupToString(int[] groupVector, int groupLabel) {
		StringBuilder sb = new StringBuilder();
		sb.append("{");
		
		for(int i = 0; i < groupVector.length; i++) {
			if(groupVector[i] == groupLabel) {
				sb.append(graph.getNodeList().get(i).getIdentifier() + ", ");
			}
		}
		
		sb.delete(sb.length() - 2, sb.length());
		sb.append("}");
		
		return sb.toString();
	}
	
	public static String groupsToString(int[] groupVector) {
		StringBuilder sb = new StringBuilder();
		
		sb.append("[");
		
		boolean moreGroups = true;
		int group = 1;
		
		while(moreGroups){
			moreGroups = false;
			
			for(int i = 0; i < groupVector.length; i++) {
				if(groupVector[i] == group) {
					sb.append(graph.getNodeList().get(i).getIdentifier() + ", ");
				}
				
				if(groupVector[i] == group + 1) {
					moreGroups = true;
				}
			}
			
			group += 1;
			
			sb.delete(sb.length() - 2, sb.length());
			sb.append("]\n[");
		}
		
		sb.delete(sb.length() - 1, sb.length());
		
		sb.append("Groups: " + (group - 1) + "\n");
		
		return sb.toString();
	}
}