/*
 * 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.annotations.NonNull
import com.android.build.gradle.internal.scope.ConventionMappingHelper
import com.android.build.gradle.internal.scope.TaskConfigAction
import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.IncrementalTask
import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.VariantType
import com.android.builder.png.QueuedCruncher
import com.android.ide.common.internal.PngCruncher
import com.android.ide.common.res2.FileStatus
import com.android.ide.common.res2.FileValidity
import com.android.ide.common.res2.MergedResourceWriter
import com.android.ide.common.res2.MergingException
import com.android.ide.common.res2.ResourceMerger
import com.android.ide.common.res2.ResourceSet
import com.android.sdklib.BuildToolInfo
import com.android.sdklib.repository.FullRevision
import com.google.common.collect.Lists
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.ParallelizableTask
import org.gradle.api.tasks.OutputFile

import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES

@ParallelizableTask
public class MergeResources extends IncrementalTask {

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

    /** Directory to write the merged resources to */
    @OutputDirectory
    File outputDir

    /** Optional file to write any publicly imported resource types and names to */
    @Optional
    @OutputFile
    File publicFile

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

    // fake input to detect changes. Not actually used by the task
    @InputFiles
    Iterable<File> getRawInputFolders() {
        return flattenSourceSets(getInputResourceSets())
    }

    @Input
    String getBuildToolsVersion() {
        getBuildTools().getRevision()
    }

    @Input
    boolean process9Patch

    @Input
    boolean crunchPng

    @Input
    boolean useNewCruncher;

    @Input
    boolean insertSourceMarkers = true

    @Input
    boolean normalizeResources

    // actual inputs
    List<ResourceSet> inputResourceSets

    private final FileValidity<ResourceSet> fileValidity = new FileValidity<ResourceSet>();

    @Override
    protected boolean isIncremental() {
        return true
    }

    private PngCruncher getCruncher() {
        if (getUseNewCruncher()) {
            if (builder.getTargetInfo().buildTools.getRevision().getMajor() >= 22) {
                return QueuedCruncher.Builder.INSTANCE.newCruncher(
                        builder.getTargetInfo().buildTools.getPath(
                                BuildToolInfo.PathId.AAPT), builder.getLogger())
            }
            logger.info("New PNG cruncher will be enabled with build tools 22 and above.")
        }
        return builder.aaptCruncher;
    }

    @Override
    protected void doFullTaskAction() {
        // this is full run, clean the previous output
        File destinationDir = getOutputDir()
        emptyFolder(destinationDir)

        List<ResourceSet> resourceSets = getInputResourceSets()

        // create a new merger and populate it with the sets.
        ResourceMerger merger = new ResourceMerger()

        try {
            for (ResourceSet resourceSet : resourceSets) {
                resourceSet.setNormalizeResources(normalizeResources)
                // set needs to be loaded.
                resourceSet.loadFromFiles(getILogger())
                merger.addDataSet(resourceSet)
            }

            // get the merged set and write it down.
            MergedResourceWriter writer = new MergedResourceWriter(
                    destinationDir, getCruncher(),
                    getCrunchPng(), getProcess9Patch(), getPublicFile())
            writer.setInsertSourceMarkers(getInsertSourceMarkers())

            merger.mergeData(writer, false /*doCleanUp*/)

            // No exception? Write the known state.
            merger.writeBlobTo(getIncrementalFolder(), writer)
        } catch (MergingException e) {
            println e.getMessage()
            merger.cleanBlob(getIncrementalFolder())
            throw new ResourceException(e.getMessage(), e)
        }
    }

    @Override
    protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) {
        // create a merger and load the known state.
        ResourceMerger merger = new ResourceMerger()
        try {
            if (!merger.loadFromBlob(getIncrementalFolder(), true /*incrementalState*/)) {
                doFullTaskAction()
                return
            }

            // compare the known state to the current sets to detect incompatibility.
            // This is in case there's a change that's too hard to do incrementally. In this case
            // we'll simply revert to full build.
            List<ResourceSet> resourceSets = getInputResourceSets()
            for (ResourceSet resourceSet : resourceSets) {
                resourceSet.setNormalizeResources(normalizeResources)
            }

            if (!merger.checkValidUpdate(resourceSets)) {
                project.logger.info("Changed Resource sets: full task run!")
                doFullTaskAction()
                return
            }

            // The incremental process is the following:
            // Loop on all the changed files, find which ResourceSet it belongs to, then ask
            // the resource set to update itself with the new file.
            for (Map.Entry<File, FileStatus> entry : changedInputs.entrySet()) {
                File changedFile = entry.getKey()

                merger.findDataSetContaining(changedFile, fileValidity)
                if (fileValidity.status == FileValidity.FileStatus.UNKNOWN_FILE) {
                    doFullTaskAction()
                    return
                } else if (fileValidity.status == FileValidity.FileStatus.VALID_FILE) {
                    if (!fileValidity.dataSet.updateWith(
                            fileValidity.sourceFile, changedFile, entry.getValue(), getILogger())) {
                        project.logger.info(
                                String.format("Failed to process %s event! Full task run",
                                        entry.getValue()))
                        doFullTaskAction()
                        return
                    }
                }
            }

            MergedResourceWriter writer = new MergedResourceWriter(
                    getOutputDir(), getCruncher(),
                    getCrunchPng(), getProcess9Patch(), getPublicFile())
            writer.setInsertSourceMarkers(getInsertSourceMarkers())
            merger.mergeData(writer, false /*doCleanUp*/)
            // No exception? Write the known state.
            merger.writeBlobTo(getIncrementalFolder(), writer)
        } catch (MergingException e) {
            println e.getMessage()
            merger.cleanBlob(getIncrementalFolder())
            throw new ResourceException(e.getMessage(), e)
        }
    }

    public static class ConfigAction implements TaskConfigAction<MergeResources> {

        @NonNull
        VariantScope scope
        @NonNull
        String taskNamePrefix
        @NonNull
        File outputLocation;
        boolean includeDependencies;
        boolean process9Patch;

        ConfigAction(VariantScope scope, String taskNamePrefix, File outputLocation,
                boolean includeDependencies, boolean process9Patch) {
            this.scope = scope
            this.taskNamePrefix = taskNamePrefix
            this.outputLocation = outputLocation
            this.includeDependencies = includeDependencies
            this.process9Patch = process9Patch

            scope.setMergeResourceOutputDir(outputLocation)
        }

        @Override
        String getName() {
            return scope.getTaskName(taskNamePrefix, "Resources")
        }

        @Override
        Class<MergeResources> getType() {
            return MergeResources
        }

        @Override
        void execute(MergeResources mergeResourcesTask) {
            BaseVariantData<? extends BaseVariantOutputData> variantData = scope.variantData

            mergeResourcesTask.androidBuilder = scope.globalScope.androidBuilder
            mergeResourcesTask.incrementalFolder = new File(
                    "$scope.globalScope.buildDir/${FD_INTERMEDIATES}/incremental/" +
                            "${taskNamePrefix}Resources/${variantData.variantConfiguration.dirName}")

            mergeResourcesTask.process9Patch = process9Patch
            mergeResourcesTask.crunchPng = scope.globalScope.extension.aaptOptions.getCruncherEnabled()
            mergeResourcesTask.normalizeResources = scope.globalScope.extension.buildToolsRevision.compareTo(new FullRevision(21, 0, 0)) < 0

            ConventionMappingHelper.map(mergeResourcesTask, "useNewCruncher") { scope.globalScope.getExtension().aaptOptions.useNewCruncher }

            ConventionMappingHelper.map(mergeResourcesTask, "inputResourceSets") {
                List<File> generatedResFolders = Lists.newArrayList(
                        scope.getRenderscriptResOutputDir(),
                        scope.getGeneratedResOutputDir())
                if (variantData.extraGeneratedResFolders != null) {
                    generatedResFolders += variantData.extraGeneratedResFolders
                }
                if (variantData.generateApkDataTask != null &&
                        variantData.getVariantConfiguration().getBuildType().isEmbedMicroApp()) {
                    generatedResFolders.add(variantData.generateApkDataTask.getResOutputDir())
                }
                variantData.variantConfiguration.getResourceSets(generatedResFolders,
                        includeDependencies)
            }

            ConventionMappingHelper.map(mergeResourcesTask, "outputDir") {
                outputLocation ?: scope.getDefaultMergeResourcesOutputDir()
            }
            variantData.mergeResourcesTask = mergeResourcesTask
        }
    }
}
