package tests.terms;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

import models.algebra.Type;
import models.algebra.Variable;
import models.dataConstraintModel.DataConstraintModel;
import models.terms.DependencyTerm;
import models.terms.EvaluatableTerm;
import models.terms.LinearRightNormalizedType;
import models.terms.Resource;
import models.terms.meta.MetaEvaluatableTermVariable;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaResource;

public class LinearRightNormalTest {

	Type INT = DataConstraintModel.typeInt;
	
	@Test
	void linearRightNormalTest() {
		
		
		Resource a = new Resource("A", INT, 2);
		Resource b = new Resource("B", INT, 2);
		Resource c = new Resource("C", INT, 2);
		Resource d = new Resource("D", INT, 2);
		Resource e = new Resource("E", INT, 2);
		Resource f = new Resource("F", INT, 2);
		Resource g = new Resource("G", INT, 1);
		
		EvaluatableTerm te1 = new DependencyTerm(e, f, g);
		EvaluatableTerm te2 = new DependencyTerm(c, d, te1);
		EvaluatableTerm te3 = new DependencyTerm(a, b, te2);
		//[a:b->[c:d->[e:f->g]]]
		assertEquals(te3.isLinearRightNormalized(), true);
		
		EvaluatableTerm te4 = new DependencyTerm(a, b, c);
		EvaluatableTerm te5 = new DependencyTerm(te4, d, e);
		EvaluatableTerm te6 = new DependencyTerm(te5, f, g);
		//[[[a:b->c]:d->e]:f->g]
		assertEquals(te6.isLinearRightNormalized(), false);
	}
	
	@Test
	void linearRightNormalizeTest() {
		
		Resource a = new Resource("A", INT, 2);
		Resource b = new Resource("B", INT, 2);
		Resource c = new Resource("C", INT, 2);
		Resource d = new Resource("D", INT, 2);
		Resource e = new Resource("E", INT, 2);
		Resource f = new Resource("F", INT, 2);
		Resource g = new Resource("G", INT, 1);
		
		EvaluatableTerm te1 = new DependencyTerm(a, b, c);
		EvaluatableTerm te2 = new DependencyTerm(te1, d, e);
		EvaluatableTerm te3 = new DependencyTerm(te2, f, g);
		
		assertEquals(te3.isLinearRightNormalized(), false);
		te3.selfLinearRightNormalize();
		assertEquals(te3.isLinearRightNormalized(), true);
	}
	
	@Test
	void linearRightNomalizedMatchTest() {
		Resource a = new Resource("A", INT, 2);
		Resource b = new Resource("B", INT, 2);
		Resource c = new Resource("C", INT, 2);
		Resource d = new Resource("D", INT, 2);
		Resource e = new Resource("E", INT, 2);
		Resource f = new Resource("F", INT, 2);
		Resource g = new Resource("G", INT, 1);
		
		EvaluatableTerm te1 = new DependencyTerm(a, b, c);
		EvaluatableTerm te2 = new DependencyTerm(te1, d, e);
		EvaluatableTerm te3 = new DependencyTerm(te2, f, g);
		
		MetaEvaluatableTermVariable metaTerm = new MetaEvaluatableTermVariable(new Variable("x"));
		MetaResource metaA = new MetaResource(new Variable("ma"));
		MetaResource metaB = new MetaResource(new Variable("mb"));
		MetaResource metaC = new MetaResource(new Variable("mc"));
		MetaRDLTerm metaTerm2 = new MetaRDLTerm(metaA, metaB, metaC);
		metaTerm2.setLinearRightNormalizedType(LinearRightNormalizedType.LINEAR_RIGHT_NORMALIZED);
		
		
		metaTerm.setLinearRightNormalizedType(LinearRightNormalizedType.LINEAR_RIGHT_NORMALIZED);
		assertEquals(metaTerm.isMatchedBy(te3), false);
		te3.selfLinearRightNormalize();
		assertEquals(metaTerm.isMatchedBy(te3), true);
		assertEquals(metaTerm2.isMatchedBy(te1), true);
	}
	
}
