package parser.builtins

import com.github.h0tk3y.betterParse.grammar.Grammar
import com.github.h0tk3y.betterParse.grammar.parseToEnd
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import parser.grammars.TermsGrammar
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.terms.Term

class DatabaseOperatorsParserTests {
    private lateinit var parser: Grammar<Term>

    @BeforeEach
    fun setup() {
        parser = TermsGrammar() as Grammar<Term>
    }

    @Test
    fun `parse assert(rule)`() {
        val input = "assert((a :- b))"
        val expected = Structure(Atom("assert"), listOf(
            Structure(Atom(":-"), listOf(
                Atom("a"),
                Atom("b")
            ))
        ))

        val result = parser.parseToEnd(input)

        assertEquals(expected, result)
    }

    @Test
    fun `parse assertA(rule)`() {
        val input = "assertA((a :- b))"
        val expected = Structure(Atom("assertA"), listOf(
            Structure(Atom(":-"), listOf(
                Atom("a"),
                Atom("b")
            ))
        ))

        val result = parser.parseToEnd(input)

        assertEquals(expected, result)
    }

    @Test
    fun `parse assertZ(rule)`() {
        val input = "assertZ((a :- b))"
        val expected = Structure(Atom("assertZ"), listOf(
            Structure(Atom(":-"), listOf(
                Atom("a"),
                Atom("b")
            ))
        ))

        val result = parser.parseToEnd(input)

        assertEquals(expected, result)
    }

    @Test
    fun `parse dynamic declaration`() {
        val input = "dynamic declaration/1"
        val expected = Structure(Atom("dynamic"), listOf(Atom("declaration/1")))

        val result = parser.parseToEnd(input)

        assertEquals(expected, result)
    }
}
