/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import androidx.build.BuildOnServerKt
import androidx.build.LibraryType
import androidx.build.SupportConfig
import androidx.build.SdkHelperKt
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("AndroidXPlugin")
    id("kotlin")
    id("com.github.johnrengelman.shadow")
}

def antlrOut = "$buildDir/generated/antlr/grammar-gen/"
sourceSets {
    main.java.srcDirs += "src/main/grammar-gen"
    main.java.srcDirs += antlrOut
}

configurations {
    /**
     * shadowed is used for dependencies which we jarjar into the library jar instead of adding it
     * as a pom dependency
     */
    shadowed
    // make sure shadowed dependencies show up as compileOnly so that normal compilation works
    compileOnly.extendsFrom(shadowed)
    // compiler tests run w/o shadowed classes so we should add those dependencies into test
    // configuration
    testCompile.extendsFrom(shadowed)
    // for downstream tests, provide a configuration that includes the shadow output + other
    // dependencies that are not shadowed
    shadowAndImplementation.extendsFrom(shadow)
    shadowAndImplementation.extendsFrom(implementation)
}

shadowJar {
    // set classifier to empty string so that it doesn't append anything to the jar.
    archiveClassifier = ""
    configurations = [project.configurations.shadowed]
    dependencies {
        // antlr has dependencies on unrelated projects for its gui stuff, do not include them
        exclude(dependency("org.abego.treelayout:.*"))
        exclude(dependency("org.glassfish:.*"))
        exclude(dependency("com.ibm.icu:.*"))
    }
    relocate("org.antlr", "androidx.room.jarjarred.org.antlr")
    relocate("org.stringtemplate", "androidx.room.jarjarred.org.stringtemplate")
}

jar {
    // set a classifier on this one so that the output does not clash with the output from
    // shadowJar task. We should never use this directly as it won't have the shadowed classes that
    // are necessary to run.
    archiveClassifier = "before-jarjar"
}

configurations {
    // replace the standard jar with the one built by 'shadowJar' in both api and runtime variants
    apiElements.outgoing.artifacts.clear()
    apiElements.outgoing.artifact(shadowJar) {
        builtBy shadowJar
    }
    runtimeElements.outgoing.artifacts.clear()
    runtimeElements.outgoing.artifact(shadowJar) {
        builtBy shadowJar
    }
}

dependencies {
    implementation(project(":room:room-common"))
    implementation(project(":room:room-migration"))
    implementation(project(":room:room-compiler-processing"))
    implementation(libs.kotlinStdlib)
    implementation(libs.autoCommon)
    implementation(libs.autoValueAnnotations)
    implementation(libs.javapoet)
    implementation(libs.kspApi)
    shadowed(libs.antlr4)
    implementation(libs.sqliteJdbc)
    implementation(libs.kotlinMetadataJvm)
    implementation(libs.apacheCommonsCodec)
    implementation(libs.intellijAnnotations)
    testImplementation(libs.truth)
    testImplementation(libs.autoValue) // to access the processor in tests
    testImplementation(libs.autoServiceAnnotations)
    testImplementation(libs.autoService) // to access the processor in tests
    testImplementation(projectOrArtifact(":paging:paging-common"))
    testImplementation(project(":room:room-compiler-processing-testing"))
    testImplementation(libs.junit)
    testImplementation(libs.jsr250)
    testImplementation(libs.mockitoCore)
    testImplementation(libs.antlr4)
    testImplementation(libs.kotlinCompilerEmbeddable)
    testImplementation(fileTree(
            dir: "${SdkHelperKt.getSdkPath(project)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
            include : "android.jar"
    ))
    testImplementation(fileTree(
            dir: provider {
                // Wrapping in a provider as we access buildDir before this project is configured
                // Replace with AGP API once it is added b/228109260
                "${new File(project(":room:room-runtime").buildDir, "intermediates/runtime_library_classes_jar/release/")}"
            },
            include : "*.jar"
    ))
    testImplementation(fileTree(
            dir: provider {
                // Wrapping in a provider as we access buildDir before this project is configured
                // Replace with AGP API once it is added b/228109260
                "${new File(project(":sqlite:sqlite").buildDir, "libJar")}"
            },
            include : "*.jar"
    ))
    testImplementation(project(":internal-testutils-common"))
}

def generateAntlrTask = task("generateAntlrGrammar", type: GenerateAntlrGrammar) {
    sqliteFile = file("$projectDir/SQLite.g4")
    antlrClasspath = configurations.compileClasspath
    outputDirectory = file(antlrOut)
}

@CacheableTask
abstract class GenerateAntlrGrammar extends DefaultTask {
    @PathSensitive(PathSensitivity.NONE)
    @InputFile
    File sqliteFile

    @Classpath
    FileCollection antlrClasspath

    @OutputDirectory
    File outputDirectory

    @Inject
    abstract ExecOperations getExecOperations()

    @Inject
    public GenerateAntlrGrammar() {
        description("Generates Antlr Grammar used by room")
        group("build")
    }

    @TaskAction
    void generateAntlrGrammar() {
        execOperations.javaexec {
            mainClass.set("org.antlr.v4.Tool")
            classpath = antlrClasspath
            args "SQLite.g4",
                 "-visitor",
                 "-o", new File(outputDirectory, "androidx/room/parser").path,
                 "-package", "androidx.room.parser"
        }
    }
}

/**
 * Room compiler jarjars some dependencies. This task validates the published artifacts of room
 * compiler to ensure dependencies are properly jarjarred.
 */
class CheckArtifactTask extends DefaultTask {
    @InputFiles
    FileCollection artifactInputs = project.objects.fileCollection()
    @InputFile
    File pomFile
    @OutputFile
    File result = new File(project.buildDir, "checkArtifactOutput.txt")
    /**
     * Checks the publish task's artifacts to make sure the classes.jar does include jarjarred
     * antlr classes.
     */
    def validatePublishTaskOutputs() {
        if (artifactInputs.files.isEmpty()) {
            throw new GradleException("Couldn't find the classes.jar for the room-compiler " +
                    "artifact. Ensure that publish is setup properly.")
        }
        artifactInputs.forEach {
            validateJarContents(it)
        }
    }

    /**
     * Traverses the given jar file, looks for the classes that should be jarjarred and validates
     * their location.
     */
    def validateJarContents(File jarFile) {
        Boolean found = false
        ZipFile zip = new ZipFile(jarFile)
        try {
            for (Enumeration list = zip.entries(); list.hasMoreElements(); ) {
                String entry = ((ZipEntry) list.nextElement()).name
                if (!entry.endsWith(".class")) continue
                if (entry.contains("org/antlr")) {
                    found = true
                    if (!entry.contains("androidx/room/jarjarred/org/antlr")) {
                        throw new GradleException("Any Antlr class included in the Room Compiler's" +
                                " jar file should be moved into androidx/room/jarjarred.\n" +
                                "Looks like $entry has not been moved")
                    }
                }
                if (!entry.startsWith("androidx/room/")) {
                    throw new GradleException("Found a class that is not in androidx.room " +
                            "package: $entry")
                }
            }
        } finally {
            zip.close()
        }
        if (!found) {
            throw new GradleException("Couldn't find any Antlr classes in room-compiler artifact" +
                    ".\n Antlr is jarjarred into room-compiler so there should be some files")
        }
    }

    /**
     * Checks the generated pom file to ensure it does not depend on any jarjarred dependencies
     * but still depends on others.
     */
    def validatePomTaskOutputs() {
        if (!pomFile.canRead()) {
            throw new GradleException("Cannot find the pom file for room-compiler")
        }
        def pomContents = pomFile.newReader().text
        if (pomContents.contains("antlr")) {
            throw new GradleException("Room-compiler pom file should not depend on antlr.\n" +
                    "Pom Contents:\n $pomContents")
        }
        if(!pomContents.contains("<artifactId>kotlin-stdlib</artifactId>")) {
            throw new GradleException("room-compiler should depend on kotlin stdlib.\n" +
                    "Pom Contents:\n $pomContents")
        }
    }

    @TaskAction
    def validate() {
        result.write("fail\n")
        validatePublishTaskOutputs()
        validatePomTaskOutputs()
        // have a no-op output to make gradle happy w/ input/output checking.
        result.write("ok\n")
    }
}

def checkArtifactContentsTask = tasks.register("checkArtifactTask", CheckArtifactTask) {
    it.artifactInputs.from {
        ((PublishToMavenRepository) project.tasks
                .named("publishMavenPublicationToMavenRepository").get()).getPublication()
                .artifacts.matching {
            it.classifier == null
        }.collect {
            it.file
        }
    }
    def pomTask = (GenerateMavenPom) project.tasks
            .named("generatePomFileForMavenPublication").get()
    it.pomFile = pomTask.destination
    it.dependsOn("publishMavenPublicationToMavenRepository")
}

// make sure we validate published artifacts on the build server.
BuildOnServerKt.addToBuildOnServer(project, checkArtifactContentsTask)

tasks.findByName("compileKotlin").dependsOn(generateAntlrTask)
tasks.findByName("sourceJar").dependsOn(generateAntlrTask)
tasks.findByName("compileKotlin").dependsOn(":room:room-runtime:bundleLibRuntimeToJarRelease")
tasks.findByName("compileKotlin").dependsOn(":sqlite:sqlite:jarRelease")

tasks.withType(KotlinCompile).configureEach {
    kotlinOptions {
        freeCompilerArgs += [
                "-Xjvm-default=all",
                "-opt-in=kotlin.RequiresOptIn",
                "-opt-in=kotlin.contracts.ExperimentalContracts",
                "-opt-in=androidx.room.compiler.processing.ExperimentalProcessingApi"
        ]
    }
}

tasks.withType(Test).configureEach {
    it.systemProperty("androidx.room.compiler.processing.strict", "true")
    it.maxParallelForks(3)
    if (project.providers.environmentVariable("GITHUB_ACTIONS").present) {
        // limit memory usage to avoid running out of memory in the docker container.
        it.maxHeapSize("512m")
    }
}

androidx {
    name = "Android Room Compiler"
    type = LibraryType.COMPILER_PLUGIN
    mavenGroup = LibraryGroups.ROOM
    inceptionYear = "2017"
    description = "Android Room annotation processor"
}
