import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import java.io.ByteArrayOutputStream
import java.nio.file.Files

buildscript {
	dependencies {
		// upgrade to latest jruby version due to a bugfix needed for Windows 10.
		// can be removed, when asciidoctorj uses this as a default version.
		classpath("org.jruby:jruby-complete:${Versions.jruby}")

		// classpath("org.asciidoctor:asciidoctorj-epub3:${Versions.asciidoctorPdf}")
		classpath("org.asciidoctor:asciidoctorj-pdf:${Versions.asciidoctorPdf}")
		classpath("org.asciidoctor:asciidoctorj-diagram:${Versions.asciidoctorDiagram}")
	}
}

plugins {
	id("org.asciidoctor.convert")
}

extra["mainJavaVersion"] = JavaVersion.VERSION_1_8
extra["testJavaVersion"] = JavaVersion.VERSION_1_8

dependencies {
	asciidoctor("org.jruby:jruby-complete:${Versions.jruby}")

	// Jupiter API is used in src/main/java
	implementation(project(":junit-jupiter-api"))

	// Pull in all "Mavenized projects" to ensure that they are included
	// in reports generated by the ApiReportGenerator.
	val mavenizedProjects: List<Project> by rootProject.extra
	mavenizedProjects
			.filter { it.name != "junit-platform-console-standalone" }
			.forEach { testImplementation(it) }

	testImplementation("org.jetbrains.kotlin:kotlin-stdlib")

	testRuntimeOnly("org.apache.logging.log4j:log4j-core:${Versions.log4j}")
	testRuntimeOnly("org.apache.logging.log4j:log4j-jul:${Versions.log4j}")

	// for ApiReportGenerator
	testImplementation("io.github.classgraph:classgraph:${Versions.classgraph}")
}

asciidoctorj {
	version = Versions.asciidoctorJ
}

val generatedAsciiDocPath = file("$buildDir/generated/asciidoc")
val consoleLauncherOptionsFile = File(generatedAsciiDocPath, "console-launcher-options.txt")
val experimentalApisTableFile = File(generatedAsciiDocPath, "experimental-apis-table.txt")
val deprecatedApisTableFile = File(generatedAsciiDocPath, "deprecated-apis-table.txt")

tasks {

	val consoleLauncherTest by registering(JavaExec::class) {
		dependsOn(testClasses)
		val reportsDir = file("$buildDir/test-results")
		outputs.dir(reportsDir)
		classpath = sourceSets["test"].runtimeClasspath
		main = "org.junit.platform.console.ConsoleLauncher"
		args("--scan-classpath")
		args("--details", "tree")
		args("--include-classname", ".*Tests")
		args("--include-classname", ".*Demo")
		args("--exclude-tag", "exclude")
		args("--reports-dir", reportsDir)
		systemProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager")
	}

	test {
		dependsOn(consoleLauncherTest)
		exclude("**/*")
	}

	val generateConsoleLauncherOptions by registering(JavaExec::class) {
		classpath = sourceSets["test"].runtimeClasspath
		main = "org.junit.platform.console.ConsoleLauncher"
		args("--help")
		redirectOutput(this, consoleLauncherOptionsFile)
	}

	val generateExperimentalApisTable by registering(JavaExec::class) {
		classpath = sourceSets["test"].runtimeClasspath
		main = "org.junit.api.tools.ApiReportGenerator"
		args("EXPERIMENTAL")
		redirectOutput(this, experimentalApisTableFile)
	}

	val generateDeprecatedApisTable by registering(JavaExec::class) {
		classpath = sourceSets["test"].runtimeClasspath
		main = "org.junit.api.tools.ApiReportGenerator"
		args("DEPRECATED")
		redirectOutput(this, deprecatedApisTableFile)
	}

	asciidoctor {
		dependsOn(generateConsoleLauncherOptions, generateExperimentalApisTable, generateDeprecatedApisTable)

		// enable the Asciidoctor Diagram extension
		requires("asciidoctor-diagram")

		separateOutputDirs = false
		sources(delegateClosureOf<PatternSet> {
			include("**/index.adoc")
		})
		resources(delegateClosureOf<CopySpec> {
			from(sourceDir) {
				include("**/images/**")
				include("tocbot-*/**")
			}
		})

		backends("html5")
		backends("pdf")
		attributes(mapOf("linkToPdf" to "true"))

		attributes(mapOf(
				"jupiter-version" to version,
				"platform-version" to project.properties["platformVersion"],
				"vintage-version" to project.properties["vintageVersion"],
				"bom-version" to version,
				"junit4-version" to Versions.junit4,
				"apiguardian-version" to Versions.apiGuardian,
				"ota4j-version" to Versions.ota4j,
				"surefire-version" to  Versions.surefire,
				"release-branch" to project.properties["releaseBranch"],
				"docs-version" to project.properties["docsVersion"],
				"revnumber" to version,
				"consoleLauncherOptionsFile" to consoleLauncherOptionsFile,
				"experimentalApisTableFile" to experimentalApisTableFile,
				"deprecatedApisTableFile" to deprecatedApisTableFile,
				"outdir" to outputDir.absolutePath,
				"source-highlighter" to "coderay@", // TODO switch to "rouge" once supported by the html5 backend and on MS Windows
				"tabsize" to "4",
				"toc" to "left",
				"icons" to "font",
				"sectanchors" to true,
				"idprefix" to "",
				"idseparator" to "-"
		))

		sourceSets["test"].apply {
			attributes(mapOf(
					"testDir" to java.srcDirs.first(),
					"testResourcesDir" to resources.srcDirs.first()
			))
			withConvention(KotlinSourceSet::class) {
				attributes(mapOf("kotlinTestDir" to kotlin.srcDirs.first()))
			}
		}
	}
}

fun redirectOutput(task: JavaExec, outputFile: File) {
	task.apply {
		outputs.file(outputFile)
		val byteStream = ByteArrayOutputStream()
		standardOutput = byteStream
		doLast {
			Files.createDirectories(outputFile.parentFile.toPath())
			Files.write(outputFile.toPath(), byteStream.toByteArray())
		}
	}
}

eclipse {
	classpath {
		plusConfigurations.add(project(":junit-platform-console").configurations["shadowed"])
		plusConfigurations.add(project(":junit-jupiter-params").configurations["shadowed"])
	}
}

idea {
	module {
		scopes["PROVIDED"]!!["plus"]!!.add(project(":junit-platform-console").configurations["shadowed"])
		scopes["PROVIDED"]!!["plus"]!!.add(project(":junit-jupiter-params").configurations["shadowed"])
	}
}
