/*
 * Copyright (C) 2012 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.
 */

package com.android.build.gradle.tasks

import com.android.build.api.component.impl.ComponentPropertiesImpl
import com.android.build.gradle.internal.LoggerWrapper
import com.android.build.gradle.internal.SdkComponentsBuildService
import com.android.build.gradle.internal.process.GradleProcessExecutor
import com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.ALL
import com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType.RENDERSCRIPT
import com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH
import com.android.build.gradle.internal.scope.InternalArtifactType.RENDERSCRIPT_LIB
import com.android.build.gradle.internal.scope.InternalArtifactType.RENDERSCRIPT_SOURCE_OUTPUT_DIR
import com.android.build.gradle.internal.services.getBuildService
import com.android.build.gradle.internal.tasks.NdkTask
import com.android.build.gradle.internal.tasks.factory.VariantTaskCreationAction
import com.android.build.gradle.internal.utils.setDisallowChanges
import com.android.build.gradle.options.BooleanOption
import com.android.builder.internal.compiler.DirectoryWalker
import com.android.builder.internal.compiler.RenderScriptProcessor
import com.android.ide.common.process.LoggedProcessOutputHandler
import com.android.ide.common.process.ProcessOutputHandler
import com.android.repository.Revision
import com.android.sdklib.BuildToolInfo
import com.android.utils.FileUtils
import com.google.common.base.Preconditions.checkNotNull
import com.google.common.collect.Lists
import com.google.common.collect.Sets
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskProvider
import org.gradle.process.ExecOperations
import java.io.File
import java.io.IOException
import java.util.concurrent.Callable
import javax.inject.Inject

/** Task to compile Renderscript files. Supports incremental update. */
@CacheableTask
abstract class RenderscriptCompile : NdkTask() {

    // ----- PUBLIC TASK API -----

    @get:OutputDirectory
    lateinit var resOutputDir: File

    @get:OutputDirectory
    lateinit var objOutputDir: File

    // ----- PRIVATE TASK API -----

    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)
    lateinit var importDirs: FileCollection

    @get:Input
    abstract val targetApi: Property<Int>

    @get:Input
    var isSupportMode: Boolean = false

    @get:Input
    var useAndroidX: Boolean = false
        private set

    @get:Input
    var optimLevel: Int = 0

    @get:Input
    var isNdkMode: Boolean = false

    @Input
    fun getBuildToolsVersion(): String =
        sdkBuildService.get().buildToolInfoProvider.get().revision.toString()

    @get:Internal
    abstract val sdkBuildService: Property<SdkComponentsBuildService>

    @get:OutputDirectory
    abstract val sourceOutputDir: DirectoryProperty

    @get:OutputDirectory
    abstract val libOutputDir: DirectoryProperty

    @get:Inject
    abstract val execOperations: ExecOperations

    // get the import folders. If the .rsh files are not directly under the import folders,
    // we need to get the leaf folders, as this is what llvm-rs-cc expects.
    // TODO: should "rsh" be a constant somewhere?
    private val importFolders: Collection<File>
        get() {
            val results = Sets.newHashSet<File>()

            val dirs = Lists.newArrayList<File>()
            dirs.addAll(importDirs.files)
            dirs.addAll(sourceDirs.files)

            for (dir in dirs) {
                DirectoryWalker.builder()
                    .root(dir.toPath())
                    .extensions("rsh")
                    .action { _, path -> results.add(path.parent.toFile()) }
                    .build()
                    .walk()
            }

            return results
        }

    private lateinit var sourceDirs: FileCollection

    @InputFiles
    @PathSensitive(PathSensitivity.RELATIVE)
    @SkipWhenEmpty
    fun getSourceDirs(): FileCollection {
        return sourceDirs.asFileTree
    }

    override fun doTaskAction() {
        // this is full run (always), clean the previous outputs
        val sourceDestDir = sourceOutputDir.get().asFile
        FileUtils.cleanOutputDir(sourceDestDir)

        val resDestDir = resOutputDir
        FileUtils.cleanOutputDir(resDestDir)

        val objDestDir = objOutputDir
        FileUtils.cleanOutputDir(objDestDir)

        val libDestDir = libOutputDir.get().asFile
        FileUtils.cleanOutputDir(libDestDir)

        val sourceDirectories = sourceDirs.files

        val buildToolsInfo = sdkBuildService.get().buildToolInfoProvider.get()
        compileAllRenderscriptFiles(
            sourceDirectories,
            importFolders,
            sourceDestDir,
            resDestDir,
            objDestDir,
            libDestDir,
            targetApi.get(),
            buildToolsInfo.revision,
            optimLevel,
            isNdkMode,
            isSupportMode,
            useAndroidX,
            ndkConfig?.abiFilters ?: setOf(),
            LoggedProcessOutputHandler(LoggerWrapper(logger)),
            buildToolsInfo
        )
    }

    /**
     * Compiles all the renderscript files found in the given source folders.
     *
     *
     * Right now this is the only way to compile them as the renderscript compiler requires all
     * renderscript files to be passed for all compilation.
     *
     *
     * Therefore whenever a renderscript file or header changes, all must be recompiled.
     *
     * @param sourceFolders all the source folders to find files to compile
     * @param importFolders all the import folders.
     * @param sourceOutputDir the output dir in which to generate the source code
     * @param resOutputDir the output dir in which to generate the bitcode file
     * @param targetApi the target api
     * @param buildToolsRevision the build tools version used
     * @param optimLevel the optimization level
     * @param ndkMode whether the renderscript code should be compiled to generate C/C++ bindings
     * @param supportMode support mode flag to generate .so files.
     * @param useAndroidX whether to use AndroidX dependencies
     * @param abiFilters ABI filters in case of support mode
     * @throws IOException failed
     * @throws InterruptedException failed
     */
    private fun compileAllRenderscriptFiles(
        sourceFolders: Collection<File>,
        importFolders: Collection<File>,
        sourceOutputDir: File,
        resOutputDir: File,
        objOutputDir: File,
        libOutputDir: File,
        targetApi: Int,
        buildToolsRevision: Revision,
        optimLevel: Int,
        ndkMode: Boolean,
        supportMode: Boolean,
        useAndroidX: Boolean,
        abiFilters: Set<String>,
        processOutputHandler: ProcessOutputHandler,
        buildToolInfo: BuildToolInfo
    ) {
        checkNotNull(sourceFolders, "sourceFolders cannot be null.")
        checkNotNull(importFolders, "importFolders cannot be null.")
        checkNotNull(sourceOutputDir, "sourceOutputDir cannot be null.")
        checkNotNull(resOutputDir, "resOutputDir cannot be null.")

        val renderscript = buildToolInfo.getPath(BuildToolInfo.PathId.LLVM_RS_CC)
        if (renderscript == null || !File(renderscript).isFile) {
            throw IllegalStateException("llvm-rs-cc is missing")
        }

        val processor = RenderScriptProcessor(
            sourceFolders,
            importFolders,
            sourceOutputDir,
            resOutputDir,
            objOutputDir,
            libOutputDir,
            buildToolInfo,
            targetApi,
            buildToolsRevision,
            optimLevel,
            ndkMode,
            supportMode,
            useAndroidX,
            abiFilters,
            LoggerWrapper(logger)
        )
        processor.build(GradleProcessExecutor(execOperations::exec), processOutputHandler)
    }

    // ----- CreationAction -----

    class CreationAction(
        componentProperties: ComponentPropertiesImpl
    ) : VariantTaskCreationAction<RenderscriptCompile, ComponentPropertiesImpl>(
        componentProperties
    ) {

        override val name: String
            get() = computeTaskName("compile", "Renderscript")

        override val type: Class<RenderscriptCompile>
            get() = RenderscriptCompile::class.java

        override fun handleProvider(
            taskProvider: TaskProvider<RenderscriptCompile>
        ) {
            super.handleProvider(taskProvider)
            creationConfig.taskContainer.renderscriptCompileTask = taskProvider
            creationConfig.artifacts.setInitialProvider(
                taskProvider,
                RenderscriptCompile::sourceOutputDir
            ).withName("out").on(RENDERSCRIPT_SOURCE_OUTPUT_DIR)

            creationConfig.artifacts.setInitialProvider(
                taskProvider,
                RenderscriptCompile::libOutputDir
            ).withName("lib").on(RENDERSCRIPT_LIB)
        }

        override fun configure(
            task: RenderscriptCompile
        ) {
            super.configure(task)

            val globalScope = creationConfig.globalScope

            val variantDslInfo = creationConfig.variantDslInfo
            val variantSources = creationConfig.variantSources

            val ndkMode = variantDslInfo.renderscriptNdkModeEnabled

            task.targetApi.set(globalScope.project.provider {
                variantDslInfo.renderscriptTarget
            })
            task.targetApi.disallowChanges()

            task.isSupportMode = variantDslInfo.renderscriptSupportModeEnabled
            task.useAndroidX = creationConfig.services.projectOptions.get(BooleanOption.USE_ANDROID_X)
            task.isNdkMode = ndkMode
            task.optimLevel = variantDslInfo.renderscriptOptimLevel

            task.sourceDirs = globalScope
                .project
                .files(Callable { variantSources.renderscriptSourceList })
            task.importDirs = creationConfig.variantDependencies.getArtifactFileCollection(
                COMPILE_CLASSPATH, ALL, RENDERSCRIPT
            )

            task.resOutputDir = creationConfig.paths.renderscriptResOutputDir
            task.objOutputDir = creationConfig.paths.renderscriptObjOutputDir

            task.ndkConfig = variantDslInfo.ndkConfig

            task.sdkBuildService.setDisallowChanges(
                getBuildService(creationConfig.services.buildServiceRegistry)
            )
            if (creationConfig.variantType.isTestComponent) {
                task.dependsOn(creationConfig.taskContainer.processManifestTask!!)
            }
        }
    }
}
