package solutions.tretter.githugandroid

enum class GitEditorCommandKind {
    COMMIT_MESSAGE,
    REBASE_TODO,
    TAG_MESSAGE,
    PATCH_HUNK,
}

data class GitEditorInvocation(
    val command: String,
    val kind: GitEditorCommandKind,
    val title: String,
    val initialContent: String = "",
)

fun parseGitEditorInvocation(command: String): GitEditorInvocation? {
    val tokens = GitSandboxEngine.tokenizeCommand(command)
    if (tokens.size < 2 || tokens[0] != "git") return null

    return when (tokens[1]) {
        "commit" -> parseGitCommitEditor(command, tokens.drop(2))
        "rebase" -> parseGitRebaseEditor(command, tokens.drop(2))
        "tag" -> parseGitTagEditor(command, tokens.drop(2))
        else -> null
    }
}

private fun parseGitCommitEditor(command: String, arguments: List<String>): GitEditorInvocation? {
    if (arguments.any { it == "--no-edit" || it == "-F" || it == "--file" || it.startsWith("--file=") }) return null
    if (arguments.containsMessageOption()) return null
    if ("-C" in arguments || "--reuse-message" in arguments || arguments.any { it.startsWith("--reuse-message=") }) return null

    return GitEditorInvocation(
        command = command,
        kind = GitEditorCommandKind.COMMIT_MESSAGE,
        title = "Edit Commit Message",
    )
}

private fun parseGitRebaseEditor(command: String, arguments: List<String>): GitEditorInvocation? {
    val interactive = arguments.any { it == "-i" || it == "--interactive" }
    if (!interactive) return null
    val target = arguments.lastOrNull { it != "-i" && it != "--interactive" && !it.startsWith("-") }
    if (target == null) return null

    return GitEditorInvocation(
        command = command,
        kind = GitEditorCommandKind.REBASE_TODO,
        title = "Edit Rebase Todo",
    )
}

private fun parseGitTagEditor(command: String, arguments: List<String>): GitEditorInvocation? {
    val needsMessage = arguments.any { it == "-a" || it == "-s" || it == "--annotate" || it == "--sign" }
    if (!needsMessage) return null
    if (arguments.any { it == "-F" || it == "--file" || it.startsWith("--file=") }) return null
    if (arguments.containsMessageOption()) return null

    return GitEditorInvocation(
        command = command,
        kind = GitEditorCommandKind.TAG_MESSAGE,
        title = "Edit Tag Message",
    )
}

private fun List<String>.containsMessageOption(): Boolean {
    return any { argument ->
        argument == "-m" ||
            argument == "--message" ||
            argument.startsWith("--message=") ||
            (argument.startsWith("-") && !argument.startsWith("--") && argument.drop(1).contains('m'))
    }
}
