/*
 * 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.SdkHelperKt
import androidx.build.SupportConfig
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

import java.util.zip.ZipEntry
import java.util.zip.ZipFile

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
    }
}

androidx.configureAarAsJarForConfiguration("testImplementation")

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.kotlinPoet)
    implementation(libs.kotlinPoetJavaPoet)
    implementation(libs.kspApi)
    shadowed(libs.antlr4)
    implementation(libs.sqliteJdbc)
    implementation(libs.kotlinMetadataJvm)
    implementation(libs.apacheCommonsCodec)
    implementation(libs.intellijAnnotations)
    testImplementation(libs.truth)
    testImplementation(libs.testParameterInjector)
    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.mockitoCore4)
    testImplementation(libs.antlr4)
    testImplementation(libs.kotlinCompilerEmbeddable)
    testImplementation(fileTree(
            dir: "${SdkHelperKt.getSdkPath(project)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
            include : "android.jar"
    ))
    testImplementationAarAsJar(project(":room:room-runtime"))
    testImplementationAarAsJar(project(":sqlite:sqlite"))
    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) {
    def pomTask = (GenerateMavenPom) project.tasks.named("generatePomFileForMavenPublication").get()
    it.pomFile = pomTask.destination
}

afterEvaluate {
    def publishTaskProvider = project.tasks.named("publishMavenPublicationToMavenRepository")
    checkArtifactContentsTask.configure {
        it.artifactInputs.from {
            publishTaskProvider.map {
                ((PublishToMavenRepository) it).getPublication().artifacts.matching {
                    it.classifier == null
                }.collect {
                    it.file
                }
            }
        }
    }
}

// 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.withType(KotlinCompile).configureEach {
    kotlinOptions {
        freeCompilerArgs += [
                "-opt-in=kotlin.contracts.ExperimentalContracts",
                "-opt-in=androidx.room.compiler.processing.ExperimentalProcessingApi",
                "-opt-in=com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview"
        ]
    }
}

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.ANNOTATION_PROCESSOR
    inceptionYear = "2017"
    description = "Android Room annotation processor"
}
