package dev.rnett.gradle.mcp.tools

import dev.rnett.gradle.mcp.gradle.GradleProjectRoot
import java.nio.file.NoSuchFileException
import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.isDirectory
import kotlin.io.path.isRegularFile
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.name
import kotlin.io.path.notExists

object GradlePathUtils {


    fun getRootProjectPath(projectRoot: GradleProjectRoot, requireGradleProject: Boolean = true): Path {
        val path = GradlePathUtils.getExistingDirPath(projectRoot)
        if (requireGradleProject) {
            if (!GradlePathUtils.isGradleRootProjectDir(path)) {
                throw IllegalArgumentException("Path is not the root of a Gradle project: $path")
            }
        }
        return path
    }

    fun getExistingPath(path: String): Path {
        val path = try {
            Path(path).toRealPath()
        } catch (e: NoSuchFileException) {
            throw IllegalArgumentException("Path ${path} does not exist", e)
        }
        if (path.notExists()) {
            throw IllegalArgumentException("Path $path does not exist")
        }
        return path
    }

    fun getExistingDirPath(root: GradleProjectRoot): Path {
        val path = getExistingPath(root.projectRoot)
        if (!path.isDirectory()) {
            throw IllegalArgumentException("Path $path is not a directory")
        }
        return path
    }

    fun isGradleProjectDir(path: Path): Boolean {
        if (path.notExists() || !path.isDirectory())
            return false

        val dirName = path.name

        return path.listDirectoryEntries("*.gradle*").any {
            it.isRegularFile() && (it.name.startsWith("build.gradle") || it.name.startsWith("$dirName.gradle"))
        }
    }

    fun isGradleRootProjectDir(path: Path): Boolean {
        if (path.notExists() || !path.isDirectory())
            return false

        return path.listDirectoryEntries("gradlew*").any {
            it.isRegularFile() && (it.name == "gradlew" || it.name == "gradlew.bat")
        }
    }

    fun getGradleVersion(projectRoot: Path): String? {
        val wrapperProps = projectRoot.resolve("gradle/wrapper/gradle-wrapper.properties")
        if (wrapperProps.isRegularFile()) {
            val props = java.util.Properties()
            wrapperProps.toFile().inputStream().use { props.load(it) }
            val distributionUrl = props.getProperty("distributionUrl")
            if (distributionUrl != null) {
                val match = Regex("gradle-([0-9.]+)-(all|bin)\\.zip").find(distributionUrl)
                return match?.groupValues?.get(1)
            }
        }
        return null
    }
}