package com.correx.apps.server.registry

import com.correx.core.transitions.graph.WorkflowGraph
import com.correx.infrastructure.workflow.WorkflowLoader
import org.slf4j.LoggerFactory
import java.nio.file.Path
import kotlin.io.path.exists
import kotlin.io.path.listDirectoryEntries

private val log = LoggerFactory.getLogger(FileSystemWorkflowRegistry::class.java)

private data class WorkflowEntry(val graph: WorkflowGraph, val description: String)

class FileSystemWorkflowRegistry(
    private val loader: WorkflowLoader,
    private val workflowsDir: Path = Path.of(
        System.getProperty("user.home"), ".config", "correx", "workflows",
    ),
) : WorkflowRegistry {

    private val cache: Map<String, WorkflowEntry> by lazy { loadAll() }

    override fun listAll(): List<WorkflowSummary> =
        cache.values.map { entry ->
            WorkflowSummary(
                workflowId = entry.graph.id,
                description = entry.description.ifBlank { entry.graph.id },
                stageIds = entry.graph.stages.keys.map { it.value },
            )
        }

    override fun find(workflowId: String): WorkflowGraph? = cache[workflowId]?.graph

    private fun loadAll(): Map<String, WorkflowEntry> {
        if (!workflowsDir.exists()) return emptyMap()
        return workflowsDir.listDirectoryEntries("*.toml")
            .mapNotNull { file ->
                runCatching {
                    val graph = loader.load(file)
                    val meta = loader.loadMeta(file)
                    WorkflowEntry(graph = graph, description = meta.description)
                }
                    .onFailure { logWarning(file, it) }
                    .getOrNull()
            }
            .associateBy { entry ->
                entry.graph.id.ifBlank { entry.graph.start.value }
            }.also { log.info("cache init done, cache keys: {}", it.keys) }
    }

    private fun logWarning(file: Path, ex: Throwable) {
        log.warn("Skipping {}: {}", file, ex.message)
    }
}
