//-- Generated by org.jetbrains.kotlin.idea.gradleJava.testing.KotlinTestTasksResolver
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
import groovy.xml.MarkupBuilder
import org.gradle.api.tasks.testing.TestDescriptor
import org.gradle.api.tasks.testing.TestListener
import org.gradle.api.tasks.testing.TestOutputEvent
import org.gradle.api.tasks.testing.TestOutputListener
import org.gradle.api.tasks.testing.TestResult
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal

class KotlinMppTestLogger {
    static def configureTestEventLogging(def task) {
        task.addTestListener(new TestListener() {
            @Override
            void beforeSuite(TestDescriptor descriptor) {
                logTestEvent("beforeSuite", (TestDescriptorInternal)descriptor, null, null)
            }

            @Override
            void afterSuite(TestDescriptor descriptor, TestResult result) {
                logTestEvent("afterSuite", (TestDescriptorInternal)descriptor, null, result)
            }

            @Override
            void beforeTest(TestDescriptor descriptor) {
                logTestEvent("beforeTest", (TestDescriptorInternal)descriptor, null, null)
            }

            @Override
            void afterTest(TestDescriptor descriptor, TestResult result) {
                logTestEvent("afterTest", (TestDescriptorInternal)descriptor, null, result)
            }
        })

        task.addTestOutputListener(new TestOutputListener() {
            @Override
            void onOutput(TestDescriptor descriptor, TestOutputEvent event) {
                logTestEvent("onOutput", (TestDescriptorInternal)descriptor, event, null)
            }
        })
    }

    static def logTestEvent(testEventType, TestDescriptorInternal testDescriptor, testEvent, testResult) {
        def writer = new StringWriter()
        def xml = new MarkupBuilder(writer)
        xml.event(type: testEventType) {
            test(id: testDescriptor.id, parentId: testDescriptor.parent?.id ?: '') {
                if (testDescriptor) {
                    descriptor(
                            name: testDescriptor.name ?: '',
                            displayName: getName(testDescriptor) ?: '',
                            className: testDescriptor.className ?: ''
                    )
                }
                if (testEvent) {
                    def message = escapeCdata(testEvent.message)
                    event(destination: testEvent.destination) {
                        xml.mkp.yieldUnescaped("$message")
                    }
                }
                if (testResult) {
                    def errorMsg = escapeCdata(testResult.exception?.message ?: '')
                    def stackTrace = escapeCdata(getStackTrace(testResult.exception))
                    result(resultType: testResult.resultType ?: '', startTime: testResult.startTime, endTime: testResult.endTime) {
                        def exception = testResult.exception
                        if (exception?.message?.trim()) xml.mkp.yieldUnescaped("<errorMsg>$errorMsg</errorMsg>")
                        if (exception) xml.mkp.yieldUnescaped("<stackTrace>$stackTrace</stackTrace>")

                        if ('kotlin.AssertionError'.equals(exception?.class?.name) || exception instanceof AssertionError) {
                            failureType('assertionFailed')
                            return
                        }

                        failureType('error')
                    }
                }
            }
        }

        writeLog(writer.toString())
    }

    static String escapeCdata(String s) {
        return "<![CDATA[" + s?.getBytes("UTF-8")?.encodeBase64()?.toString() + "]]>";
    }

    static def wrap(String s) {
        if (!s) return s;
        s.replaceAll("\r\n|\n\r|\n|\r", "<ijLogEol/>\n")
    }

    static def writeLog(s) {
        println String.format("\n<ijLog>%s</ijLog>", wrap(s))
    }

    static def logTestReportLocation(def report) {
        if (!report) return
        def writer = new StringWriter()
        def xml = new MarkupBuilder(writer)
        xml.event(type: 'reportLocation', testReport: report)
        writeLog(writer.toString());
    }

    static def logConfigurationError(aTitle, aMessage, boolean openSettings) {
        def writer = new StringWriter()
        def xml = new MarkupBuilder(writer)
        xml.event(type: 'configurationError', openSettings: openSettings) {
            title(aTitle)
            message(aMessage)
        }
        writeLog(writer.toString());
    }

    static def getStackTrace(Throwable t) {
        if (!t) return ''
        StringWriter sw = new StringWriter()
        t.printStackTrace(new PrintWriter(sw))
        sw.toString()
    }

    static def getName(TestDescriptorInternal descriptor) {
        try {
            return descriptor.getDisplayName() // available starting from ver. 4.10.3
        }
        catch (Throwable ignore) {
            return descriptor.getName()
        }
    }
}
//
//-- Generated by org.jetbrains.kotlin.idea.gradleJava.configuration.KotlinGradleCoroutineDebugProjectResolver
gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
    taskGraph.allTasks.each { Task task ->
        if (!(task instanceof Test || task instanceof JavaExec)) return
        
        for (arg in task.getAllJvmArgs() + task.getJvmArgs()) {
            if (arg == "-Dkotlinx.coroutines.debug=off") {
                return
            }
        }

        FileCollection taskClasspath = task.classpath
        task.jvmArgumentProviders.add(new CommandLineArgumentProvider() {
            private static def VERSION_PATTERN = java.util.regex.Pattern.compile(/(\d+)\.(\d+)(\.(\d+))?.*/)
        
            @Override
            Iterable<String> asArguments() {
                List<String> emptyList = Collections.emptyList()
                if (System.getProperty("idea.debugger.dispatch.port") == null) return emptyList
                def kotlinxCoroutinesCoreJar = taskClasspath.find { it.name.startsWith("kotlinx-coroutines-core") && !it.name.contains("sources") }
                if (kotlinxCoroutinesCoreJar == null) return emptyList
                def results = (kotlinxCoroutinesCoreJar.getName() =~ /kotlinx-coroutines-core(\-jvm)?-(\d[\w\.\-]+)\.jar$/).findAll()
                if (results.isEmpty()) return emptyList
                String version = results.first()[2]
                def matcher = VERSION_PATTERN.matcher(version)
                try {
                    if (!matcher.matches()) return emptyList
                    int major = Integer.parseInt(matcher.group(1)) 
                    int minor = Integer.parseInt(matcher.group(2))
                    int patch = Integer.parseInt(matcher.group(4) ?: "0")
                    if (major < 1 || (major == 1 && (minor < 5 || (minor == 5 && patch < 1)))) return emptyList
                } catch (NumberFormatException ignored) {
                    return emptyList
                }
                return ["-javaagent:${kotlinxCoroutinesCoreJar?.absolutePath}", "-ea"]
            }
        })
    }
}
//