plugins {
    id 'java-library'
    id 'maven-publish'
    id 'signing'
    id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
    id 'com.gorylenko.gradle-git-properties' version '2.5.3' apply false
    id 'com.github.ben-manes.versions' version '0.53.0'
    id 'net.researchgate.release' version '3.1.0'
}

ext {
    // Project constants
    github_org = 'Discord4J'
    project_name = 'Discord4J'
    artifact_group = 'com.discord4j'
    project_version = "$version".toString()
    project_description = 'Java interface for the Discord API'
    project_url = 'https://discord4j.com'
    project_jdk = '1.8'
    jdk = JavaVersion.current().majorVersion
    jdk_javadoc = "https://docs.oracle.com/javase/$jdk/docs/api/".toString()
    if (JavaVersion.current().isJava11Compatible()) {
        jdk_javadoc = "https://docs.oracle.com/en/java/javase/$jdk/docs/api/".toString()
    }

    // Dependencies
    reactor_bom_version = '2023.0.17'
    jackson_databind_version = '2.17.0'
    jackson_datatype_jsr310_version = '2.17.0'
    jackson_datatype_jdk8_version = '2.17.0'
    caffeine_version = '2.9.3'
    immutables_group = 'org.immutables'
    immutables_version = '2.10.1'

    // Test dependencies
    junit_version = '5.7.1'
    mockito_version = '3.11.2'
    logback_version = '1.3.14'
    reflections_version = '0.9.12'
    lavaplayer_version = '1.4.3'

    isJitpack = "true" == System.getenv("JITPACK")
    isRelease = !version.toString().endsWith('-SNAPSHOT')
}

allprojects {
    apply plugin: 'java-library'
    apply plugin: 'com.github.ben-manes.versions'
    apply plugin: 'maven-publish'
    if (!isJitpack && isRelease) {
        apply plugin: 'signing'
    }

    group = artifact_group
    version = project_version
    description = project_description

    java {
        sourceCompatibility = project_jdk
        targetCompatibility = project_jdk
    }

    dependencies {
        api platform("io.projectreactor:reactor-bom:$reactor_bom_version")
        api "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_datatype_jsr310_version"
        api "com.discord4j:discord-json:$discordJsonVersion"

        compileOnly "com.google.code.findbugs:jsr305:3.0.1"
        testCompileOnly "com.google.code.findbugs:jsr305:3.0.1"
    }

    repositories {
        mavenLocal()
        mavenCentral()
        if (!isRelease || isJitpack) {
            maven { url 'https://central.sonatype.com/repository/maven-snapshots' }
        }
        maven { url 'https://m2.dv8tion.net/releases' }
        maven { url 'https://jitpack.io' }
    }

    configurations.configureEach {
        resolutionStrategy.cacheChangingModulesFor 60, 'seconds'
    }

    tasks.withType(Javadoc).configureEach {
        setFailOnError(false) // TODO: This is just for the issue with links, need handle this better
        options {
            encoding = 'UTF-8'
            tags = ["apiNote:a:API Note:",
                    "implSpec:a:Implementation Requirements:",
                    "implNote:a:Implementation Note:"]
            addStringOption 'Xdoclint:none', '-quiet'
            addStringOption 'encoding', 'UTF-8'
            // adding links to javadocs for filling specific classes when not existing inside current javadoc
            links = [
                jdk_javadoc,
                "https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/2.17.0/",
                "https://www.reactive-streams.org/reactive-streams-1.0.4-javadoc/",
                "https://projectreactor.io/docs/core/3.6.16/api/",
                "https://projectreactor.io/docs/netty/1.1.29/api/",
                "https://projectreactor.io/docs/extra/3.5.2/api/",
                "https://netty.io/4.1/api/"
            ]
        }
        if (JavaVersion.current().isJava9Compatible()) {
            options.addBooleanOption('html5', true)
        }
        if (JavaVersion.current().isJava11Compatible() && !JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) {
            options.addBooleanOption('-no-module-directories', true)
        }
    }

    tasks.withType(JavaCompile).configureEach {
        options.encoding = 'UTF-8'
        options.incremental = true
    }

    tasks.register('downloadDependencies') {
        description 'Download all dependencies to the Gradle cache'
        doLast {
            configurations.findAll { it.canBeResolved }.files
        }
    }

    java {
        withJavadocJar()
        withSourcesJar()
    }
}

subprojects {

    base {
        archivesName = "discord4j-$project.name"
    }

    tasks.withType(Javadoc).configureEach {
        title = "${base.archivesName.get()} ${version} API"
        options.windowTitle = "${base.archivesName.get()} ($version)"
    }

    publishing {
        publications {
            mavenJava(MavenPublication) {
                from components.java
                afterEvaluate {
                    artifactId = jar.archiveBaseName.get()
                }

                versionMapping {
                    usage('java-api') {
                        fromResolutionOf('runtimeClasspath')
                    }
                    usage('java-runtime') {
                        fromResolutionResult()
                    }
                }

                pom {
                    name = 'Discord4J'
                    description = 'A JVM-based REST/WS wrapper for the official Discord Bot API'
                    url = 'https://github.com/Discord4J/Discord4J'
                    organization {
                        name = 'Discord4J'
                        url = 'https://discord4j.com'
                    }
                    issueManagement {
                        system = 'GitHub'
                        url = 'https://github.com/Discord4J/Discord4J/issues'
                    }
                    licenses {
                        license {
                            name = 'LGPL-3.0'
                            url = 'https://github.com/Discord4J/Discord4J/LICENSE.txt'
                            distribution = 'repo'
                        }
                    }
                    scm {
                        url = 'https://github.com/Discord4J/Discord4J'
                        connection = 'scm:git:git://github.com/Discord4J/Discord4J.git'
                        developerConnection = 'scm:git:ssh://git@github.com:Discord4J/Discord4J.git'
                    }
                    developers {
                        developer {
                            name = 'The Discord4J Team'
                        }
                    }
                }
            }
        }

        if (!isJitpack) {
            repositories {
                maven {
                    if (isRelease) {
                        url 'https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2'
                    } else {
                        url 'https://central.sonatype.com/repository/maven-snapshots'
                    }
                    def sonatypeUsername = findProperty('sonatypeUsername')
                    def sonatypePassword = findProperty('sonatypePassword')
                    if (sonatypeUsername != null && sonatypePassword != null) {
                        credentials {
                            username sonatypeUsername
                            password sonatypePassword
                        }
                    }
                }
            }
        }
    }

    if (!isJitpack && isRelease) {
        signing {
            def signingKey = findProperty("signingKey")
            def signingPassword = findProperty("signingPassword")
            if (signingKey != null && signingPassword != null) {
                useInMemoryPgpKeys(new String(signingKey.decodeBase64()), signingPassword as String)
            }
            sign publishing.publications.mavenJava
        }
    }
}

nexusPublishing {
    repositories {
        sonatype {
            nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
            snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
            def sonatypeUsername = findProperty('sonatypeUsername')
            def sonatypePassword = findProperty('sonatypePassword')
            if (sonatypeUsername != null && sonatypePassword != null) {
                username = sonatypeUsername
                password = sonatypePassword
            }
        }
    }
}

def buildDocsUrl(String project) {
    def docVersion = isRelease ? "$version" : "3.2"
    return "https://javadoc.io/doc/com.discord4j/$project/$docVersion/" as String
}

release {
    preTagCommitMessage = 'Release version'
    tagCommitMessage = 'Release version'
    newVersionCommitMessage = 'Next development version'
    git {
        requireBranch.set('')
    }
}

tasks.register('updateReadme') {
    if (isRelease && !version.contains('M') && !version.contains('RC')) {
        doLast {
            copy {
                from '.github/README_TEMPLATE.md'
                into '.'
                rename { 'README.md' }
                expand version: version
            }
        }
    }
}

preTagCommit.dependsOn updateReadme

wrapper {
    distributionType = Wrapper.DistributionType.ALL
}
