package inference.rewrite;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.terms.DependencyTerm;
import models.terms.EvaluatableTerm;
import models.terms.Resource;

public class ResourceTree {
	
	private Resource root;
	private Map<Position, List<Position>> tree;
	private Map<Position, Resource> resourceMap;
	
	public ResourceTree(EvaluatableTerm term) {
		tree = new HashMap<>();
		resourceMap = new HashMap<>();
		constructResourceTree(term, new Position(List.of(0)));
	}
	
	private Position constructResourceTree(EvaluatableTerm term, Position top) {
		if (term instanceof Resource resource) {
			resourceMap.put(top, resource);
			return top;
		} else if (term instanceof DependencyTerm depTerm) {
			EvaluatableTerm dependingTerm = depTerm.getDependingTerm();
			List<Resource> dependedResources = depTerm.getDependedResources(); 
			List<EvaluatableTerm> argumentTerms = depTerm.getArgumentTerms();
			Position nextPosition = constructResourceTree(dependingTerm, top);
			Position resultPosition = nextPosition;
			tree.put(nextPosition, new ArrayList<>());
			for (int i = 0; i < dependedResources.size(); i++) {
				Position nextPos = nextPosition.addPath(i);
				tree.get(nextPosition).add(nextPos);
				resultPosition = constructResourceTree(dependedResources.get(i), nextPos);
				Position nextNextPos = resultPosition.addPath(0);
				tree.put(resultPosition, new ArrayList<>());
				tree.get(resultPosition).add(nextNextPos);
				resultPosition = constructResourceTree(argumentTerms.get(i), nextNextPos);
			}
			return resultPosition;
		} else {
			return null;
		}
	}
	
	@Override
	public String toString() {
		return tree.toString();
	}
	
	public void debug(Position pos) {
		System.out.println(pos + ", " + resourceMap.get(pos));
		if (tree.containsKey(pos)) {
			for (Position nextPos : tree.get(pos)) {
				debug(nextPos);
			}
		}
	}
	
}

