package be.jeffcheasey88.peeratcode.bonus.extract;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;

import be.jeffcheasey88.peeratcode.framework.RequestType;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.Router;

//A noter que le but est d'extraire des informations sans modifier le code source,
//comme les tests unitaire, ici je veux générer un élément textuel qui me donnera l'état des routes,
//je ne vais donc pas modifier la classe router pour donner un accès au route.
public class RouteExtracter {
	
	private Router router;
	
	public RouteExtracter(Router router){
		this.router = router;
	}

	public void extract() throws Exception{
		Field field = Router.class.getDeclaredField("responses");
		field.setAccessible(true);
		Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
		for(Entry<RequestType, Map<Response, Route>> types : responses.entrySet()){
			for(Entry<Response, Route> routes : types.getValue().entrySet()){
				System.out.println("["+types.getKey()+"] ("+routes.getValue().needLogin()+") "+routes.getValue().path());
			}
		}
	}
	
	public void extractDoc() throws Exception{
		Field field = Router.class.getDeclaredField("responses");
		field.setAccessible(true);
		Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
		for(Map<Response, Route> route : responses.values()){
			for(Response response : route.keySet()){
				Method method = response.getClass().getDeclaredMethod("exec",
						Response.class.getDeclaredMethods()[0].getParameterTypes());
				for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
					System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
				}
			}
		}
	}
}
