/*
 * 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.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)

def tasksThatDependOnAntlr = ["compileKotlin", "sourceJar", "kotlinSourcesJar", "generateKmpDocs"]
tasks.matching { tasksThatDependOnAntlr.contains(it.name) }.configureEach {
    it.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"
}
