/*
 * Copyright (C) 2014 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.SdkConstants
import com.android.build.api.artifact.ArtifactType
import com.android.build.api.variant.BuiltArtifacts
import com.android.build.api.variant.impl.BuiltArtifactsImpl
import com.android.build.api.variant.impl.VariantOutputImpl
import com.android.build.api.variant.impl.dirName
import com.android.build.api.variant.impl.getApiString
import com.android.build.gradle.internal.LoggerWrapper
import com.android.build.gradle.internal.component.LibraryCreationConfig
import com.android.build.gradle.internal.profile.ProfileAwareWorkAction
import com.android.build.gradle.internal.scope.InternalArtifactType
import com.android.build.gradle.internal.scope.InternalArtifactType.MANIFEST_MERGE_REPORT
import com.android.build.gradle.internal.tasks.factory.VariantTaskCreationAction
import com.android.build.gradle.internal.tasks.manifest.mergeManifests
import com.android.manifmerger.ManifestMerger2
import com.android.manifmerger.MergingReport
import com.android.utils.FileUtils
import com.google.common.annotations.VisibleForTesting
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskProvider
import java.io.File
import java.io.IOException
import java.io.UncheckedIOException

/** a Task that only merge a single manifest with its overlays.  */
@CacheableTask
abstract class ProcessLibraryManifest : ManifestProcessorTask() {

    @get:OutputFile
    abstract val manifestOutputFile: RegularFileProperty

    @get:Optional
    @get:Input
    abstract val packageOverride: Property<String>

    @get:PathSensitive(PathSensitivity.RELATIVE)
    @get:InputFiles
    abstract val manifestOverlays: ListProperty<File>

    @get:Optional
    @get:Input
    abstract val manifestPlaceholders: MapProperty<String, Any>

    /** The processed Manifests files folder.  */
    @get:OutputDirectory
    abstract val packagedManifestOutputDirectory: DirectoryProperty

    /**
     * The aapt friendly processed Manifest. In case we are processing a library manifest, some
     * placeholders may not have been resolved (and will be when the library is merged into the
     * importing application). However, such placeholders keys are not friendly to aapt which flags
     * some illegal characters. Such characters are replaced/encoded in this version.
     */
    @get:Optional
    @get:OutputDirectory
    abstract val aaptFriendlyManifestOutputDirectory: DirectoryProperty
    /**
     * The aapt friendly processed Manifest. In case we are processing a library manifest, some
     * placeholders may not have been resolved (and will be when the library is merged into the
     * importing application). However, such placeholders keys are not friendly to aapt which flags
     * some illegal characters. Such characters are replaced/encoded in this version.
     */
    @get:Internal
    val aaptFriendlyManifestOutputFile: File?
        get() = if (aaptFriendlyManifestOutputDirectory.isPresent) FileUtils.join(
            aaptFriendlyManifestOutputDirectory.get().asFile,
            mainSplit.get().dirName(),
            SdkConstants.ANDROID_MANIFEST_XML
        ) else null

    @VisibleForTesting
    @get:Nested
    abstract val mainSplit: Property<VariantOutputImpl>

    private var isNamespaced = false

    override fun doFullTaskAction() {
        workerExecutor.noIsolation().submit(ProcessLibWorkAction::class.java) {
            it.initializeFromAndroidVariantTask(this)
            it.variantName.set(variantName)
            it.aaptFriendlyManifestOutputFile.set(aaptFriendlyManifestOutputFile)
            it.namespaced.set(isNamespaced)
            it.mainManifest.set(mainManifest.get())
            it.manifestOverlays.set(manifestOverlays)
            it.packageOverride.set(packageOverride)
            it.minSdkVersion.set(minSdkVersion)
            it.targetSdkVersion.set(targetSdkVersion)
            it.maxSdkVersion.set(maxSdkVersion)
            it.manifestOutputFile.set(manifestOutputFile)
            it.manifestPlaceholders.set(manifestPlaceholders)
            it.reportFile.set(reportFile)
            it.mergeBlameFile.set(mergeBlameFile)
            it.manifestOutputDirectory.set(packagedManifestOutputDirectory)
            it.aaptFriendlyManifestOutputDirectory.set(aaptFriendlyManifestOutputDirectory)
            it.mainSplit.set(mainSplit.get().toSerializedForm())
        }
    }

    abstract class ProcessLibParams: ProfileAwareWorkAction.Parameters() {
        abstract val variantName: Property<String>
        abstract val aaptFriendlyManifestOutputFile: RegularFileProperty
        abstract val namespaced: Property<Boolean>
        abstract val mainManifest: RegularFileProperty
        abstract val manifestOverlays: ListProperty<File>
        abstract val packageOverride: Property<String>
        abstract val minSdkVersion: Property<String>
        abstract val targetSdkVersion: Property<String>
        abstract val maxSdkVersion: Property<Int>
        abstract val manifestOutputFile: RegularFileProperty
        abstract val manifestPlaceholders: MapProperty<String, Any>
        abstract val reportFile: RegularFileProperty
        abstract val mergeBlameFile: RegularFileProperty
        abstract val manifestOutputDirectory: DirectoryProperty
        abstract val aaptFriendlyManifestOutputDirectory: DirectoryProperty
        abstract val mainSplit: Property<VariantOutputImpl.SerializedForm>
}

    abstract class ProcessLibWorkAction : ProfileAwareWorkAction<ProcessLibParams>() {
        override fun run() {
            val optionalFeatures: Collection<ManifestMerger2.Invoker.Feature> =
                if (parameters.namespaced.get()) listOf(
                    ManifestMerger2.Invoker.Feature.FULLY_NAMESPACE_LOCAL_RESOURCES
                ) else emptyList()
            val mergingReport = mergeManifests(
                parameters.mainManifest.asFile.get(),
                parameters.manifestOverlays.get(), emptyList(), emptyList(),
                null,
                parameters.packageOverride.get(),
                null,
                null,
                parameters.minSdkVersion.orNull,
                parameters.targetSdkVersion.orNull,
                parameters.maxSdkVersion.orNull,
                parameters.manifestOutputFile.asFile.get().absolutePath,
                parameters.aaptFriendlyManifestOutputFile.asFile.orNull?.absolutePath,
                ManifestMerger2.MergeType.LIBRARY /* outInstantRunManifestLocation */,
                parameters.manifestPlaceholders.get() /* outInstantAppManifestLocation */,
                optionalFeatures,
                emptyList(),
                parameters.reportFile.asFile.get(), LoggerWrapper.getLogger(ProcessLibraryManifest::class.java)
            )
            val mergedXmlDocument =
                mergingReport.getMergedXmlDocument(MergingReport.MergedManifestKind.MERGED)
            try {
                outputMergeBlameContents(
                    mergingReport,
                    parameters.mergeBlameFile.asFile.get()
                )
            } catch (e: IOException) {
                throw UncheckedIOException(e)
            }
            val properties =
                if (mergedXmlDocument != null) mapOf(
                    "packageId" to mergedXmlDocument.packageName,
                    "split" to mergedXmlDocument.splitName
                ) else mapOf()
            if (parameters.manifestOutputDirectory.isPresent) {
                BuiltArtifactsImpl(
                    BuiltArtifacts.METADATA_FILE_VERSION,
                    InternalArtifactType.PACKAGED_MANIFESTS,
                    parameters.packageOverride.get(),
                    parameters.variantName.get(),
                    listOf(
                        parameters.mainSplit.get().toBuiltArtifact(
                            parameters.manifestOutputFile.asFile.get(), properties
                        )
                    )
                )
                    .saveToDirectory(parameters.manifestOutputDirectory.asFile.get())
            }
            if (parameters.aaptFriendlyManifestOutputDirectory.isPresent) {
                BuiltArtifactsImpl(
                    BuiltArtifacts.METADATA_FILE_VERSION,
                    InternalArtifactType.AAPT_FRIENDLY_MERGED_MANIFESTS,
                    parameters.packageOverride.get(),
                    parameters.variantName.get(),
                    listOf(
                        parameters.mainSplit.get().toBuiltArtifact(
                            parameters.aaptFriendlyManifestOutputFile.asFile.get(), properties
                        )
                    )
                )
                    .saveToDirectory(parameters.aaptFriendlyManifestOutputDirectory.asFile.get())
            }
        }

    }

    @get:Optional
    @get:Input
    abstract val minSdkVersion: Property<String?>

    @get:Optional
    @get:Input
    abstract val targetSdkVersion: Property<String?>

    @get:Optional
    @get:Input
    abstract val maxSdkVersion: Property<Int?>

    @get:PathSensitive(PathSensitivity.RELATIVE)
    @get:InputFile
    abstract val mainManifest: Property<File>

    class CreationAction
    /** `EagerTaskCreationAction` for the library process manifest task.  */(creationConfig: LibraryCreationConfig) :
        VariantTaskCreationAction<ProcessLibraryManifest, LibraryCreationConfig>(creationConfig) {
        override val name: String
            get() = computeTaskName("process", "Manifest")

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

        override fun handleProvider(
            taskProvider: TaskProvider<ProcessLibraryManifest>
        ) {
            super.handleProvider(taskProvider)
            creationConfig.taskContainer.processManifestTask = taskProvider
            val artifacts = creationConfig.artifacts
            artifacts.setInitialProvider(
                taskProvider,
                ProcessLibraryManifest::aaptFriendlyManifestOutputDirectory
            ).withName("aapt").on(InternalArtifactType.AAPT_FRIENDLY_MERGED_MANIFESTS)

            artifacts.setInitialProvider(
                taskProvider,
                ProcessLibraryManifest::packagedManifestOutputDirectory
            ).on(InternalArtifactType.PACKAGED_MANIFESTS)

            artifacts.setInitialProvider(
                taskProvider
            ) { task: ProcessLibraryManifest -> task.manifestOutputFile }
                .on(ArtifactType.MERGED_MANIFEST)

            artifacts.setInitialProvider(
                taskProvider,
                ProcessLibraryManifest::mergeBlameFile
            ).withName("manifest-merger-blame-" + creationConfig.baseName + "-report.txt")
                .on(InternalArtifactType.MANIFEST_MERGE_BLAME_FILE)

            artifacts.setInitialProvider(
                taskProvider,
                ProcessLibraryManifest::reportFile
            )
                .atLocation(
                    FileUtils.join(creationConfig.globalScope.outputsDir, "logs")
                        .absolutePath
                )
                .withName("manifest-merger-" + creationConfig.baseName + "-report.txt")
                .on(MANIFEST_MERGE_REPORT)
        }

        override fun configure(
            task: ProcessLibraryManifest
        ) {
            super.configure(task)
            val variantDslInfo = creationConfig.variantDslInfo
            val variantSources = creationConfig.variantSources
            val project = creationConfig.globalScope.project
            task.minSdkVersion
                .set(project.provider { creationConfig.minSdkVersion.getApiString() })
            task.minSdkVersion.disallowChanges()
            task.targetSdkVersion
                .set(
                    project.provider {
                        val targetSdkVersion =
                            creationConfig.targetSdkVersion
                        if (targetSdkVersion.apiLevel < 0) {
                            return@provider null
                        }
                        targetSdkVersion.apiString
                    }
                )
            task.targetSdkVersion.disallowChanges()
            task.maxSdkVersion
                .set(project.provider(creationConfig::maxSdkVersion))
            task.maxSdkVersion.disallowChanges()
            task.mainSplit.set(project.provider { creationConfig.outputs.getMainSplit() })
            task.mainSplit.disallowChanges()
            task.isNamespaced =
                creationConfig.globalScope.extension.aaptOptions.namespaced
            task.packageOverride.set(creationConfig.applicationId)
            task.packageOverride.disallowChanges()
            task.manifestPlaceholders.set(
                task.project.provider(
                    variantDslInfo::manifestPlaceholders
                )
            )
            task.manifestPlaceholders.disallowChanges()
            task.mainManifest
                .set(project.provider(variantSources::mainManifestFilePath))
            task.mainManifest.disallowChanges()
            task.manifestOverlays.set(
                task.project.provider(variantSources::manifestOverlays)
            )
            task.manifestOverlays.disallowChanges()
        }
    }
}
