/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package test.exceptions

import test.supportsSuppressedExceptions
import kotlin.test.*

class ExceptionTest {
    private val cause = Exception("cause")

    @Test fun throwable() = testCreateException(::Throwable, ::Throwable, ::Throwable, ::Throwable)
    @Test fun error() = testCreateException(::Error, ::Error, ::Error, ::Error)
    @Test fun exception() = testCreateException(::Exception, ::Exception, ::Exception, ::Exception)
    @Test fun runtimeException() = testCreateException(::RuntimeException, ::RuntimeException, ::RuntimeException, ::RuntimeException)
    @Test fun illegalArgumentException() = testCreateException(::IllegalArgumentException, ::IllegalArgumentException, ::IllegalArgumentException, ::IllegalArgumentException)
    @Test fun illegalStateException() = testCreateException(::IllegalStateException, ::IllegalStateException, ::IllegalStateException, ::IllegalStateException)
    @Test fun indexOutOfBoundsException() = testCreateException(::IndexOutOfBoundsException, ::IndexOutOfBoundsException)
    @Test fun unsupportedOperationException() = testCreateException(::UnsupportedOperationException, ::UnsupportedOperationException, ::UnsupportedOperationException, ::UnsupportedOperationException)
    @Test fun numberFormatException() = testCreateException(::NumberFormatException, ::NumberFormatException)
    @Test fun nullPointerException() = testCreateException(::NullPointerException, ::NullPointerException)
    @Test fun classCastException() = testCreateException(::ClassCastException, ::ClassCastException)
    @Test fun noSuchElementException() = testCreateException(::NoSuchElementException, ::NoSuchElementException)
    @Test fun concurrentModificationException() = testCreateException(::ConcurrentModificationException, ::ConcurrentModificationException)
    @Test fun arithmeticException() = testCreateException(::ArithmeticException, ::ArithmeticException)

    @Test fun noWhenBranchMatchedException() = @Suppress("DEPRECATION_ERROR") testCreateException(::NoWhenBranchMatchedException, ::NoWhenBranchMatchedException, ::NoWhenBranchMatchedException, ::NoWhenBranchMatchedException)
    @Test fun uninitializedPropertyAccessException() = @Suppress("DEPRECATION_ERROR") testCreateException(::UninitializedPropertyAccessException, ::UninitializedPropertyAccessException, ::UninitializedPropertyAccessException, ::UninitializedPropertyAccessException)

    @Test fun assertionError() = testCreateException(::AssertionError, ::AssertionError, ::AssertionError)


    private fun <T : Throwable> testCreateException(
        noarg: () -> T,
        fromMessage: (String?) -> T,
        fromCause: ((Throwable?) -> T)? = null,
        fromMessageCause: ((String?, Throwable?) -> T)? = null
    ) {
        noarg().let { e ->
            assertEquals(null, e.message)
            assertEquals(null, e.cause)
        }

        fromMessage("message").let { e ->
            assertEquals("message", e.message)
            assertEquals(null, e.cause)
        }

        fromMessage(null).let { e ->
            assertTrue(e.message == null || e.message == "null")
        }

        fromMessageCause?.run {
            invoke("message", cause).let { e ->
                assertEquals("message", e.message)
                assertSame(cause, e.cause)
            }
            invoke(null, null).let { e ->
                assertEquals(null, e.message)
                assertEquals(null, e.cause)
            }
        }

        fromCause?.invoke(cause)?.let { e ->
            assertSame(cause, e.cause)
        }
    }

    @Test
    fun suppressedExceptions() {
        val e1 = Throwable()

        val c1 = Exception("Suppressed 1")
        val c2 = Exception("Suppressed 2")

        assertTrue(e1.suppressedExceptions.isEmpty())

        e1.addSuppressed(c1)
        e1.addSuppressed(c2)

        if (supportsSuppressedExceptions) {
            assertEquals(listOf(c1, c2), e1.suppressedExceptions)
        } else {
            assertTrue(e1.suppressedExceptions.isEmpty())
        }
    }

    @Test
    fun exceptionDetailedTrace() {
        fun root(): Nothing = throw IllegalStateException("Root cause\nDetails: root")

        fun suppressedError(id: Int): Throwable = UnsupportedOperationException("Side error\nId: $id")

        fun induced(): Nothing {
            try {
                root()
            } catch (e: Throwable) {
                for (id in 0..1)
                    e.addSuppressed(suppressedError(id))
                throw RuntimeException("Induced", e)
            }
        }

        val e = try {
            induced()
        } catch (e: Throwable) {
            e.apply { addSuppressed(suppressedError(2)) }
        }

        val topLevelTrace = e.stackTraceToString()
        fun assertInTrace(value: Any) {
            if (value.toString() !in topLevelTrace) {
                fail("Expected top level trace: $topLevelTrace\n\nto contain: $value")
            }
        }

        assertInTrace(e)

        val cause = assertNotNull(e.cause, "Should have cause")
        assertInTrace(cause)

        if (supportsSuppressedExceptions) {
            val topLevelSuppressed = e.suppressedExceptions.single()
            assertInTrace(topLevelSuppressed)
            cause.suppressedExceptions.forEach {
                assertInTrace(it)
            }
        }

//        fail(topLevelTrace) // to dump the entire trace
    }

    @Test
    fun circularSuppressedDetailedTrace() {
        if (!supportsSuppressedExceptions) return

        // Testing an exception of the following structure
        // e1
        //    -- suppressed: e0 (same stack as e1)
        //    -- suppressed: e3
        //       -- suppressed: e1
        // Caused by: e2
        //    -- suppressed: e1
        // Caused by: e3

        val e3 = Exception("e3")
        val e2 = Error("e2", e3)
        val (e1, e0) = listOf("e1", "e0").map { msg -> RuntimeException(msg, e2.takeIf { msg == "e1" }) }
        e1.addSuppressed(e0)
        e1.addSuppressed(e3)
        e3.addSuppressed(e1)
        e2.addSuppressed(e1)

        val topLevelTrace = e1.stackTraceToString()
        fun assertAppearsInTrace(value: Any, count: Int) {
            if (Regex.fromLiteral(value.toString()).findAll(topLevelTrace).count() != count) {
                fail("Expected to find $value $count times in $topLevelTrace")
            }
        }
        assertAppearsInTrace(e1, 3)
        assertAppearsInTrace(e0, 1)
        assertAppearsInTrace(e2, 1)
        assertAppearsInTrace(e3, 2)
//        fail(topLevelTrace) // to dump the entire trace
    }

}