package rekursion_test

/* ---------------------------------------------------------------- *
 * UNIT TESTING
 * ---------------------------------------------------------------- */

import (
	"logik/aussagenlogik/rekursion"
	"logik/aussagenlogik/schema"
	"logik/aussagenlogik/syntaxbaum"
	"logik/core/utils"
	"testing"

	"github.com/stretchr/testify/assert"
)

/* ---------------------------------------------------------------- *
 * TESTCASE eval(·, ·)
 * ---------------------------------------------------------------- */

func TestRekursivEvalLiteral(test *testing.T) {
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var I []string
	var val int
	tree, _ = schema.ParseExpr("A0")
	I = []string{"A0"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
	tree, _ = schema.ParseExpr("A0")
	I = []string{}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 0)
	tree, _ = schema.ParseExpr("! A0")
	I = []string{"A0"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 0)
	tree, _ = schema.ParseExpr("! A0")
	I = []string{}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
}

func TestRekursivEvalComplex1(test *testing.T) {
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var I []string
	var val int
	tree, _ = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || A2 ))")
	I = []string{"A0", "A2"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
	I = []string{"A0", "A3"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
	I = []string{"A0"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 0)
	I = []string{"A4", "A8"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
}

func TestRekursivEvalComplex2(test *testing.T) {
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var I []string
	var val int
	tree, _ = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || ! A2 ))")
	I = []string{"A0", "A2"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 0)
	I = []string{"A0", "A3"}
	val = rekursion.RekursivEval(tree, I)
	assert.Equal(val, 1)
}

/* ---------------------------------------------------------------- *
 * TESTCASE Atoms(·)
 * ---------------------------------------------------------------- */

func TestRekursivAtomsNoduplicates(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val []string
	tree, _ = schema.ParseExpr("( A4 && ( A4 || A4 ))")
	val = rekursion.RekursivAtoms(tree)
	var n int = len(utils.FilterStrings(&val, func(x string) bool { return x == "A4" }))
	assert.Equal(n, 1, "Atome dürfen nicht mehrfach vorkommen!")
}

func TestRekursivAtomsNononatoms(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	test.Skip("Syntax for generic expressions in ANTLR4 g4 needs to be implemented.")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val []string
	tree, _ = schema.ParseExpr("( {F} || A3 )")
	val = rekursion.RekursivAtoms(tree)
	utils.SortStrings(&val)
	assert.NotContains(val, "F", "Nichtatomare Formeln dürfen nicht vorkommen!")
}

func TestRekursivAtomsCalc1(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val []string
	tree, _ = schema.ParseExpr("A0")
	val = rekursion.RekursivAtoms(tree)
	utils.SortStrings(&val)
	assert.Equal(val, []string{"A0"})
}

func TestRekursivAtomsCalc2(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val []string
	tree, _ = schema.ParseExpr("((( ! A8 && A3 ) || A4 ) && A0 )")
	val = rekursion.RekursivAtoms(tree)
	utils.SortStrings(&val)
	assert.Equal(val, []string{"A0", "A3", "A4", "A8"})
}

/* ---------------------------------------------------------------- *
 * TESTCASE depth(·, ·)
 * ---------------------------------------------------------------- */

func TestRekursivDepthCalc1(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("A0")
	val = rekursion.RekursivDepth(tree)
	assert.Equal(val, 0)
}

func TestRekursivDepthCalc2(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("!! A8")
	val = rekursion.RekursivDepth(tree)
	assert.Equal(val, 2)
}

func TestRekursivDepthCalc3(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("( ! A0 && A3 )")
	val = rekursion.RekursivDepth(tree)
	assert.Equal(val, 2)
}

func TestRekursivDepthCalc4(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivDepth(tree)
	assert.Equal(val, 4)
}

func TestRekursivDepthCalc5(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivDepth(tree)
	assert.Equal(val, 5)
}

/* ---------------------------------------------------------------- *
 * TESTCASE length(·)
 * ---------------------------------------------------------------- */

func TestRekursivLengthCalc1(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("A0")
	val = rekursion.RekursivLength(tree)
	assert.Equal(val, 1)
}

func TestRekursivLengthCalc2(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("!! A8")
	val = rekursion.RekursivLength(tree)
	assert.Equal(val, 3)
}

func TestRekursivLengthCalc3(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("( ! A0 && A3 )")
	val = rekursion.RekursivLength(tree)
	assert.Equal(val, 4)
}

func TestRekursivLengthCalc4(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivLength(tree)
	assert.Equal(val, 8)
}

func TestRekursivLengthCalc5(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivLength(tree)
	assert.Equal(val, 9)
}

/* ---------------------------------------------------------------- *
 * TESTCASE #Parentheses(·)
 * ---------------------------------------------------------------- */

func TestRekursivParenthesesCalc1(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("A0")
	val = rekursion.RekursivParentheses(tree)
	assert.Equal(val, 0)
}

func TestRekursivParenthesesCalc2(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("!! A8")
	val = rekursion.RekursivParentheses(tree)
	assert.Equal(val, 0)
}

func TestRekursivParenthesesCalc3(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("( ! A0 && A3 )")
	val = rekursion.RekursivParentheses(tree)
	assert.Equal(val, 2)
}

func TestRekursivParenthesesCalc4(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivParentheses(tree)
	assert.Equal(val, 6)
}

func TestRekursivParenthesesCalc5(test *testing.T) {
	test.Skip("Methode noch nicht implementiert")
	var assert = assert.New(test)
	var tree syntaxbaum.SyntaxBaum
	var val int
	tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
	val = rekursion.RekursivParentheses(tree)
	assert.Equal(val, 6)
}