package com.correx.core.tasks

import com.correx.core.events.types.ProjectId
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class GitTaskSyncTest {

    private val store = InMemoryEventStore()
    private val service = TaskService(store)
    private val sync = GitTaskSync(service)
    private val project = ProjectId("auth")

    @Test
    fun `a closing keyword drives a task to DONE and re-running is idempotent`() = runBlocking {
        val id = service.createTask(project, "JWT", "g").taskId // auth-1, TODO

        val report = sync.sync(listOf(Commit("abc1234567def", "fix auth-1: rotate tokens")))

        assertEquals(TaskStatus.DONE, service.getTask(id)?.state?.status)
        val change = report.changes.single()
        assertEquals("auth-1", change.key)
        assertEquals("TODO", change.from)
        assertEquals("DONE", change.to)
        assertEquals("abc1234", change.sha)
        // The same commit applied again advances nothing.
        assertTrue(sync.sync(listOf(Commit("abc1234567def", "fix auth-1"))).changes.isEmpty())
    }

    @Test
    fun `a plain mention advances only to IN_PROGRESS`() = runBlocking {
        val id = service.createTask(project, "JWT", "g").taskId

        sync.sync(listOf(Commit("def4567", "wip on auth-1")))

        assertEquals(TaskStatus.IN_PROGRESS, service.getTask(id)?.state?.status)
    }

    @Test
    fun `blocked tasks and unknown keys are left alone`() = runBlocking {
        val id = service.createTask(project, "JWT", "g").taskId
        service.claim(id, "x")
        service.block(id, "waiting on infra")

        val report = sync.sync(listOf(Commit("a1", "fix auth-1"), Commit("b2", "closes auth-999")))

        assertEquals(TaskStatus.BLOCKED, service.getTask(id)?.state?.status)
        assertTrue(report.changes.isEmpty())
    }

    @Test
    fun `each advance leaves a git provenance note`() = runBlocking {
        val id = service.createTask(project, "JWT", "g").taskId

        sync.sync(listOf(Commit("abc1234567", "closes auth-1")))

        assertTrue(service.getTask(id)!!.state.notes.any { it.body.contains("git abc1234") })
    }
}
