#!/usr/bin/env kotlin

/*
 * Copyright 2024 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.
 */

/**
 * To run .kts files, follow these steps:
 *
 * 1. Download and install the Kotlin compiler (kotlinc). There are several ways to do this; see
 *    https://kotlinlang.org/docs/command-line.html
 * 2. Run the script from the command line:
 *    <path_to>/kotlinc -script <script_file>.kts <arguments>
 */

@file:Repository("https://repo1.maven.org/maven2")
@file:DependsOn("com.google.code.gson:gson:2.11.0")

import java.io.File
import java.util.Locale
import kotlin.system.exitProcess
import com.google.gson.Gson

if (args.isEmpty() || !args.contains("-input")) {
    println("Expected path to buildHealth Advice json file using -input.")
    println("Provide output file path using -output. By default, output.csv will be generated " +
        "in the current directory")
    println("Usage ex: kotlinc -script buildHealthAdviceToCsv.main.kts -- -input " +
        "path/to/build-health-report.json -output /path/to/output.csv")
    exitProcess(1)
}

val input = args[1]
if (!File(input).exists()) {
    println("Could not find input files: $input")
    exitProcess(1)
}
val inputJsonFile = File(input)
println("Parsing ${inputJsonFile.path}...")

val outputFile = if(args.contains("-output")) {
    args[3]
} else {
    "output.csv"
}

val csvOutputFile = File(outputFile)
if(csvOutputFile.exists()) {
    csvOutputFile.delete()
}

val csvData = StringBuilder()
val columnHeaders = listOf(
    "ID", // leave blank
    "Priority",
    "Summary",
    "HotlistIds",
    "Assignee", // leave blank
    "Status",
    "ComponentPath",
    "Reporter",
    "FirstNote"
)
csvData.append(columnHeaders.joinToString(","))
csvData.append("\n")

val gson = Gson()
val advice: Advice = gson.fromJson(inputJsonFile.readLines().first(), Advice::class.java)

//list of projects we want to file issues for
//val androidxProjects = listOf("lint", "lint-checks", "buildSrc-tests", "androidx-demos", "stableaidl", "test")
//val flanProjects = listOf("activity", "fragment", "lifecycle", "navigation")

var numProjects = 0
advice.projectAdvice.forEach projectAdvice@{ projectAdvice ->
    val projectPath = projectAdvice.projectPath
    val title = "Please fix misconfigured dependencies for $projectPath"

    val project = projectPath.split(":")[1]

//    Uncomment the following section if you want to create bugs for specific projects
//    if(project !in flanProjects) {
//        return@projectAdvice
//    }

    val description = StringBuilder()
    description.appendLine(
        "The dependency analysis gradle plugin found some dependencies that may have been " +
            "misconfigured. Please fix the following dependencies: \n"
    )

    val unused = mutableSetOf<String>()
    val transitive = mutableSetOf<String>()
    val modified = mutableSetOf<String>()
    projectAdvice.dependencyAdvice.forEach { dependencyAdvice ->
        val fromConfiguration = dependencyAdvice.fromConfiguration
        val toConfiguration = dependencyAdvice.toConfiguration
        val coordinates = dependencyAdvice.coordinates
        val resolvedVersion = coordinates.resolvedVersion

        val isCompileOnly = toConfiguration?.endsWith("compileOnly", ignoreCase = true) == true
        val isModifyDependencyAdvice = fromConfiguration != null && toConfiguration != null
        val isTransitiveDependencyAdvice = fromConfiguration == null && toConfiguration != null && !isCompileOnly
        val isUnusedDependencyAdvice = fromConfiguration != null && toConfiguration == null

        var identifier = if(resolvedVersion == null) {
            "'${coordinates.identifier}'"
        } else {
            "'${coordinates.identifier}:${coordinates.resolvedVersion}'"
        }
        if (coordinates.type == "project") {
            identifier = "project($identifier)"
        }
        if (isModifyDependencyAdvice) {
            modified.add("$toConfiguration($identifier) (was $fromConfiguration)")
        }
        if(isTransitiveDependencyAdvice) {
            transitive.add("$toConfiguration($identifier)")
        }
        if(isUnusedDependencyAdvice) {
            unused.add("$fromConfiguration($identifier)")
        }
    }

    if(unused.isNotEmpty()) {
        description.appendLine("Unused dependencies which should be removed:")
        description.appendLine("```")
        description.appendLine(unused.sorted().joinToString(separator = "\n"))
        description.appendLine("```")

    }
    if (transitive.isNotEmpty()) {
        description.appendLine("These transitive dependencies can be declared directly:")
        description.appendLine("```")
        description.appendLine(transitive.sorted().joinToString(separator = "\n"))
        description.appendLine("```")
    }
    if (modified.isNotEmpty()) {
        description.appendLine(
            "These dependencies can be modified to be as indicated. Please be careful " +
                "while changing the type of dependencies since it can affect the consumers of " +
                "this library. To learn more about the various dependency configurations, " +
                "please visit: [dac]" +
                "(https://developer.android.com/build/dependencies#dependency_configurations). " +
                "Also check [Gradle's guide for dependency management]" +
                "(https://docs.gradle.org/current/userguide/dependency_management.html).\n"
        )
        description.appendLine("```")
        description.appendLine(modified.sorted().joinToString(separator = "\n"))
        description.appendLine("```")
    }

    description.appendLine("To get more up-to-date project advice, please run:")
    description.appendLine("```")
    description.appendLine("./gradlew $projectPath:projectHealth")
    description.appendLine("```")
    val newColumns = listOf(
        "NEW00000", // ID
        "P2", // priority
        title,
        "=HYPERLINK(\"https://issuetracker.google.com/issues?q=status%3Aopen%20hotlistid%3A(5997499)\", \"Androidx misconfigured dependencies\")",
        "", // Assignee: leave blank
        "Assigned", // status
        "Android > Android OS & Apps > Jetpack (androidx) > ${project.replaceFirstChar {
            if (it.isLowerCase()) it.titlecase(
                Locale.getDefault()
            ) else it.toString()
        }}",
        "", // reporter: add your ldap here
        description.toString()
    )

    if (projectAdvice.dependencyAdvice.isNotEmpty()) {
        numProjects++
        csvData.append(newColumns.joinToString(",") { data ->
            "\"${data.replace("\"", "\"\"")}\""
        })
        csvData.append("\n")
    }
}

csvOutputFile.appendText(csvData.toString())
println("Wrote CSV output to ${csvOutputFile.path} for $numProjects projects")

data class Advice(
    val projectAdvice: List<ProjectAdvice>,
)

data class ProjectAdvice(
    val projectPath: String,
    val dependencyAdvice: List<DependencyAdvice>,
    val pluginAdvice: List<PluginAdvice>,
)

data class DependencyAdvice(
    val coordinates: Coordinates,
    val fromConfiguration: String?,
    val toConfiguration: String?
)

data class Coordinates(
    val type: String,
    val identifier: String,
    val resolvedVersion: String?
)

data class PluginAdvice(
    val redundantPlugin: String,
    val reason: String
)
