package interpreter

import io.Logger
import parser.ScriptParser
import prolog.ast.Database
import prolog.ast.Database.Program
import prolog.ast.logic.Clause
import prolog.ast.logic.Predicate

class FileLoader {
    private val parser = ScriptParser()

    fun load(filePath: String) {
        Logger.info("Loading file: $filePath")

        val input = readFile(filePath)

        Logger.debug("Parsing content of $filePath")
        val clauses: List<Clause> = parser.parse(input)

        Logger.debug("Adding clauses to program")
        addToProgram(clauses, filePath)

        Logger.debug("Finished loading file: $filePath")
    }

    fun readFile(filePath: String): String {
        try {
            Logger.debug("Reading $filePath")
            val file = java.io.File(filePath)

            if (!file.exists()) {
                Logger.error("File $filePath does not exist")
                throw IllegalArgumentException("File not found: $filePath")
            }

            return file.readText()
        } catch (e: Exception) {
            Logger.error("Error reading file: $filePath")
            throw RuntimeException("Error reading file: $filePath", e)
        }
    }

    fun addToProgram(clauses: List<Clause>, filePath: String) {
        Logger.debug("Grouping clauses by functor")
        val groupedClauses = clauses.groupBy { it.functor }
        val predicates: List<Predicate> = groupedClauses.map { (_, clauses) ->
            Predicate(clauses)
        }

        val database = Database(filePath)
        predicates.forEach { database.load(it) }
        Program.consult(database)
    }
}