/*
 * Copyright (C) 2018 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.internal.tasks.structureplugin

import com.android.build.gradle.internal.plugins.BasePlugin
import com.android.ide.common.symbols.IdProvider
import com.android.ide.common.symbols.parseResourceSourceSetDirectory
import com.android.resources.ResourceType
import com.android.sdklib.AndroidTargetHash
import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.file.RegularFile
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskAction
import java.io.File

open class GatherModuleInfoTask : DefaultTask() {
    private lateinit var sourceProjectName : String
    lateinit var outputProvider : Provider<RegularFile>
        private set
    private var moduleDataHolder = ModuleInfo()

    @TaskAction
    fun action() {
        AndroidCollector().collectInto(moduleDataHolder, this)
        DependencyCollector().collectInto(moduleDataHolder, this)
        KotlinUsageCollector().collectInto(moduleDataHolder, this)
        SourceFilesCollector().collectInto(moduleDataHolder, this)

        // Transform the ":" from the path into "_" so Poet can generate directories for each module
        // correctly. Example: :module1:submoduleA will become module1_submoduleA
        moduleDataHolder.name = sourceProjectName.replace(':', '_')
        moduleDataHolder.saveAsJsonTo(outputProvider.get().asFile)
    }

    class ConfigAction(private val project: Project) : Action<GatherModuleInfoTask> {
        override fun execute(task: GatherModuleInfoTask) {
            task.sourceProjectName = project.name
            task.outputProvider = project.layout.buildDirectory.file("local-module-info.json")
        }
    }
}

private interface DataCollector {
    fun collectInto(dataHolder: ModuleInfo, task: GatherModuleInfoTask)
}

private class AndroidCollector : DataCollector {
    override fun collectInto(dataHolder: ModuleInfo, task: GatherModuleInfoTask) {
        if (!task.project.isAndroidProject()) return
        dataHolder.type = ModuleType.ANDROID
        task.project.plugins.withType(BasePlugin::class.java).firstOrNull()?.let {
            collectBuildConfig(dataHolder, it)
            collectResources(dataHolder, it)
        }
    }

    private fun collectBuildConfig(dataHolder: ModuleInfo, plugin: BasePlugin) {
        plugin.extension.defaultConfig.minSdkVersion?.apiLevel?.let {
            dataHolder.androidBuildConfig.minSdkVersion = it }
        plugin.extension.defaultConfig.targetSdkVersion?.apiLevel?.let {
            dataHolder.androidBuildConfig.targetSdkVersion = it }

        // extension.compileSdkVersion returns "android-27", we want just "27".
        dataHolder.androidBuildConfig.compileSdkVersion =
                AndroidTargetHash.getPlatformVersion(plugin.extension.compileSdkVersion)!!.apiLevel
    }

    private fun collectResources(dataHolder: ModuleInfo, plugin: BasePlugin) {
        val resources = plugin.extension.sourceSets
            .findByName(SourceSet.MAIN_SOURCE_SET_NAME)?.res ?: return

        resources.srcDirs.forEach {
            val symbolTable = parseResourceSourceSetDirectory(it, IdProvider.constant(), null)

            // TODO add more resource types as ASPoet supports them
            dataHolder.resources.imageCount +=
                    symbolTable.getSymbolByResourceType(ResourceType.DRAWABLE).size
            dataHolder.resources.layoutCount +=
                    symbolTable.getSymbolByResourceType(ResourceType.LAYOUT).size
            dataHolder.resources.stringCount +=
                    symbolTable.getSymbolByResourceType(ResourceType.STRING).size
        }
    }
}

private class SourceFilesCollector : DataCollector {
    override fun collectInto(dataHolder: ModuleInfo, task: GatherModuleInfoTask) {
        // Get the java sources from main (excludes tests for now) or just return if they are
        // not there, since we do not have anything else to do.
        val javaPackageMap = mutableMapOf<String, Int>()
        val kotlinPackageMap = mutableMapOf<String, Int>()

        task.project.findMainSourceSet().forEach {
            it.walkBottomUp().toList().filter { !it.isDirectory }
                .forEach {
                    val dirPackage = it.parent
                    when (it.extension) {
                        "java" -> javaPackageMap.increment(dirPackage)
                        "kt" -> kotlinPackageMap.increment(dirPackage)
                    }
                }
        }

        dataHolder.javaSourceInfo.packages = javaPackageMap.size
        if (javaPackageMap.isNotEmpty()) {
            // Since ASPoet doesn't support count per package, we pick the biggest.
            dataHolder.javaSourceInfo.classesPerPackage = javaPackageMap.values.max() ?: 0
            dataHolder.javaSourceInfo.methodsPerClass = 10 // TODO actually count the methods
            dataHolder.javaSourceInfo.fieldsPerClass = 10 // TODO actually count the fields
        }

        dataHolder.kotlinSourceInfo.packages = kotlinPackageMap.size
        if (kotlinPackageMap.isNotEmpty()) {
            // Since ASPoet doesn't support count per package, we pick the biggest.
            dataHolder.kotlinSourceInfo.classesPerPackage = kotlinPackageMap.values.max() ?: 0
            dataHolder.kotlinSourceInfo.methodsPerClass = 10 // TODO actually count the methods
            dataHolder.kotlinSourceInfo.fieldsPerClass = 10 // TODO actually count the methods
        }
    }

    private fun Project.findMainSourceSet(): Set<File> {
        if (isAndroidProject()) {
            val androidPlugin = plugins.withType(BasePlugin::class.java).first()
            return androidPlugin.extension.sourceSets
                .findByName(SourceSet.MAIN_SOURCE_SET_NAME)?.java?.srcDirs ?: emptySet()
        } else {
            val javaPlugin =
                convention.findPlugin(JavaPluginConvention::class.java) ?: return emptySet()
            return javaPlugin.sourceSets
                .findByName(SourceSet.MAIN_SOURCE_SET_NAME)?.allSource?.srcDirs ?: emptySet()
        }
    }

    private fun MutableMap<String, Int>.increment(key: String) {
        this[key] = (this[key] ?: 0) + 1
    }
}

private class KotlinUsageCollector : DataCollector {
    override fun collectInto(dataHolder: ModuleInfo, task: GatherModuleInfoTask) {
        if (task.project.usesKotlin()) dataHolder.useKotlin = true
    }

    private fun Project.usesKotlin(): Boolean {
        return (isAndroidProject() && plugins.hasPlugin("kotlin-android")) ||
                plugins.hasPlugin("kotlin")
    }
}

private class DependencyCollector : DataCollector {
    val relevantConfigurations = setOf(
        "api", "implementation", "classpath",
        "compile", "compileOnly",
        "runtime", "runtimeOnly",
        "testImplementation", "testCompile",
        "androidTestImplementation", "androidTestCompile",
        "annotationProcessor", "kapt",
        "package", "provided", "wearApp"
    )

    override fun collectInto(dataHolder: ModuleInfo, task: GatherModuleInfoTask) {
        val projectDependencies = task.project.configurations.asIterable()
            .filter { relevantConfigurations.contains(it.name) }
            .flatMap { gatherDependencies(it) }.asIterable()
            .cleanDependencies(task.project)

        dataHolder.dependencies.addAll(projectDependencies)
    }

    private fun gatherDependencies(config: Configuration): List<PoetDependenciesInfo> {
        val deps = mutableListOf<PoetDependenciesInfo>()

        for (dependency in config.allDependencies) when (dependency) {
                is ProjectDependency -> PoetDependenciesInfo(
                    DependencyType.MODULE,
                    config.name,
                    // For sub modules, drop the first ":" from the path and transform the others
                    // into "_" so Poet can generate directories for each module correctly.
                    dependency.dependencyProject.path.drop(1).replace(':', '_')
                )
                is ModuleDependency -> PoetDependenciesInfo(
                    DependencyType.EXTERNAL_LIBRARY,
                    config.name,
                    "${dependency.group}:${dependency.name}:${dependency.version}"
                )
                else -> null
            }?.let { deps.add(it) }
        return deps
    }

    private fun Iterable<PoetDependenciesInfo>.cleanDependencies(project: Project): Iterable<PoetDependenciesInfo> {
        var filteredDependencies = this

        // Java modules that have the "kotlin" plugin applied creates repeated dependencies for
        // kotlin jdk, so here we remove them to not pollute the resulting file.
        if (project.plugins.hasPlugin("java-library") && project.plugins.hasPlugin("kotlin")) {
            // Keep only the compile dependency if it's org.jetbrains.kotlin:kotlin-stdlib-jdk.
            filteredDependencies = filteredDependencies.filter {
                !it.dependency.startsWith("org.jetbrains.kotlin:kotlin-stdlib-jdk") ||
                        it.scope == "compile"
            }
        }

        return filteredDependencies
    }

}

private fun Project.isAndroidProject(): Boolean {
    // "com.android.application", "com.android.library", "com.android.test"
    return plugins.withType(BasePlugin::class.java).count() > 0
}
