package ua.ansymo.hintco.test

import org.junit.Test
import ua.ansymo.hintco.AlgebraicLoopVariantProcessor
import ua.ansymo.hintco.CandidatesGenerator
import ua.ansymo.hintco.ConstraintChecker
import ua.ansymo.hintco.CosimUnitInstance
import ua.ansymo.hintco.ModelQuery
import ua.ansymo.hintco.ModelStorage

import static org.junit.Assert.*

class AlgebraicLoopProcessingTests {
	
	@Test
	def void addConstraintsWithAlgebraicLoopsTest() {
		val loader = new ModelStorage()
		
		val src = loader.loadCandidates("instances/algebraic_loop_opt_test.hintco")
		
		val generator = new CandidatesGenerator(new ConstraintChecker(), [n, alternatives, ns |
				true
			],
			[ns, vId, constraints, cs |
				val scenario = ModelQuery.findRootScenario(ns)
				val cosimUnits = scenario.cosimunits.filter(CosimUnitInstance)
				val A = cosimUnits.findFirst[u | u.identifier=="A"]
				val B = cosimUnits.findFirst[u | u.identifier=="B"]
				assertTrue(A.inputPorts.findFirst[p|p.identifier=="3fromB"].precedes.contains(A))
				assertTrue(A.inputPorts.findFirst[p|p.identifier=="5fromC"].precedes.contains(A))
				assertFalse(B.inputPorts.findFirst[p|p.identifier=="10fromC"].precedes.contains(B))
			])
		generator.createVariantTree(src)
		generator.generateVariants(src, 1, true)
	}
	
	@Test
	def void transformToCosimUnitGraphTest(){
		val loader = new ModelStorage()
		
		val src = loader.loadCandidates("instances/algebraic_loop_opt_test.hintco")
		
		val generator = new CandidatesGenerator(new ConstraintChecker(), [n, alternatives, ns |
				true
			],
			[ns, vId, constraints, cs |
				val scenario = ModelQuery.findRootScenario(ns)
				
				val graph = new AlgebraicLoopVariantProcessor(null).transformToCosimUnitGraph(scenario)
				
				assertNotNull(graph)
		
				val vertices = graph.vertexSet
				assertEquals(3, vertices.size)
				val A = vertices.findFirst[v | v.identifier == "A"]
				val B = vertices.findFirst[v | v.identifier == "B"]
				val C = vertices.findFirst[v | v.identifier == "C"]
				
				val A4B = graph.getAllEdges(A, B).head
				val B3A = graph.getAllEdges(B, A).head
				val B3C = graph.getAllEdges(B, C).head
				
				assertNotNull(A4B)
				assertNotNull(B3A)
				assertNotNull(B3C)
				assertTrue(graph.getAllEdges(C, B).isEmpty)
				assertEquals(4.0,graph.getEdgeWeight(A4B),1e-4)
				assertEquals(3.0,graph.getEdgeWeight(B3A),1e-4)
				assertEquals(3.0,graph.getEdgeWeight(B3C),1e-4)
			])
		generator.createVariantTree(src)
		generator.generateVariants(src, 1, true)
	}
	
}