package models.meta;

import lombok.Getter;
import models.Dependency;
import models.EvaluatableTerm;
import models.RDLTerm;
import models.ResourceVariable;
import models.algebra.Symbol;

@Getter
public class MetaRDLTerm extends RDLTerm {

	protected static enum TermType {
		META_DEPENDENCY,
		META_DEPENDENCY_VARIABLE,
		META_DEPENDENCY_TERM,
		META_DEPENDENCY_TERM_VARIABLE,
		META_EVALUATABLE_TERM_VARIABLE,
		META_RESOURCE_VARIABLE;
	}
	
	protected TermType termType;
	
	protected MetaRDLTerm(Symbol symbol, int order, TermType termType) {
		super(symbol, order);
		this.termType = termType;
	}
	
	//dependency
	public MetaRDLTerm(RDLTerm dependingTerm, MetaResourceVariable dependedVariable) {
		super(new Symbol(":", 2), dependedVariable.getOrder());
		addChild(dependingTerm);
		addChild(dependedVariable);
		this.termType = TermType.META_DEPENDENCY;
	}
	
	public MetaRDLTerm(MetaRDLTerm dependingTerm, ResourceVariable dependedVariable) {
		super(new Symbol(":", 2), dependedVariable.getOrder());
		addChild(dependingTerm);
		addChild(dependedVariable);
		this.termType = TermType.META_DEPENDENCY;
	}
	
	//list type dependency
	public MetaRDLTerm(MetaRDLTerm dependency) {
		super(new Symbol(":", 1), dependency.getOrder() - 1);
		addChild(dependency);
		this.termType = TermType.META_DEPENDENCY;
	}
	
	//dependency term
	public MetaRDLTerm(Dependency dependency, MetaRDLTerm argumentVariable) {
		super(
			new Symbol(":", 3), 
			dependency.getDependedVariable().getOrder() == argumentVariable.getOrder() 
				? dependency.getDependedVariable().getOrder() 
				: dependency.getDependedVariable().getOrder() - 1
		);
		addChild(dependency.getDependingTerm());
		addChild(dependency.getDependedVariable());
		addChild(argumentVariable);
		this.termType = TermType.META_DEPENDENCY_TERM;
	}
	
	public MetaRDLTerm(MetaRDLTerm dependency, EvaluatableTerm argumentVariable) {
		super(
			new Symbol(":", 3), 
			((RDLTerm) dependency.getChild(1)).getOrder() == argumentVariable.getOrder() 
				? ((RDLTerm) dependency.getChild(1)).getOrder()
				: ((RDLTerm) dependency.getChild(1)).getOrder() - 1
		);
		addChild(dependency.getChild(0));
		addChild(dependency.getChild(1));
		addChild(argumentVariable);
		this.termType = TermType.META_DEPENDENCY_TERM;
	}

	@Override
	public String toString() {
		return null;
	}

	@Override
	public String toStringWithOrder() {
		return null;
	}

}
