package com.yorvana.util

import android.content.Context
import com.google.common.truth.Truth.assertThat
import io.mockk.every
import io.mockk.mockk
import org.junit.Test
import java.io.File

class CrashReporterTest {
    @Test
    fun `install should set uncaught exception handler and write to file`() {
        val context = mockk<Context>(relaxed = true)
        val tempDir =
            kotlin.io.path
                .createTempDirectory()
                .toFile()

        every { context.applicationContext.getExternalFilesDir(null) } returns tempDir
        every { context.applicationContext.filesDir } returns tempDir

        // Capture the original handler to restore it later
        val originalHandler = Thread.getDefaultUncaughtExceptionHandler()

        CrashReporter.install(context)

        val newHandler = Thread.getDefaultUncaughtExceptionHandler()
        assertThat(newHandler).isNotEqualTo(originalHandler)

        // Trigger the new handler artificially
        val exception = RuntimeException("Test Crash")
        try {
            newHandler?.uncaughtException(Thread.currentThread(), exception)
        } catch (e: Exception) {
            // Ignore any re-thrown exceptions from the default handler (which might be null or cause tests to fail)
        }

        // Restore original
        Thread.setDefaultUncaughtExceptionHandler(originalHandler)

        // Verify the file was written
        val crashFile = File(tempDir, "crash.log")
        assertThat(crashFile.exists()).isTrue()
        val content = crashFile.readText()
        assertThat(content).contains("=== CRASH REPORT ===")
        assertThat(content).contains("Test Crash")

        tempDir.deleteRecursively()
    }

    @Test
    fun `read should return null if file does not exist`() {
        val context = mockk<Context>(relaxed = true)
        val tempDir =
            kotlin.io.path
                .createTempDirectory()
                .toFile()

        every { context.applicationContext.getExternalFilesDir(null) } returns tempDir

        val content = CrashReporter.read(context)
        assertThat(content).isNull()

        tempDir.deleteRecursively()
    }

    @Test
    fun `read should return content if file exists`() {
        val context = mockk<Context>(relaxed = true)
        val tempDir =
            kotlin.io.path
                .createTempDirectory()
                .toFile()

        every { context.applicationContext.getExternalFilesDir(null) } returns tempDir

        File(tempDir, "crash.log").writeText("Crash data")

        val content = CrashReporter.read(context)
        assertThat(content).isEqualTo("Crash data")

        tempDir.deleteRecursively()
    }

    @Test
    fun `clear should delete the file`() {
        val context = mockk<Context>(relaxed = true)
        val tempDir =
            kotlin.io.path
                .createTempDirectory()
                .toFile()

        every { context.applicationContext.getExternalFilesDir(null) } returns tempDir

        val crashFile = File(tempDir, "crash.log")
        crashFile.writeText("Crash data")
        assertThat(crashFile.exists()).isTrue()

        CrashReporter.clear(context)
        assertThat(crashFile.exists()).isFalse()

        tempDir.deleteRecursively()
    }
}
