import Foundation
import Testing

@testable import NucleicCore

@Suite("gh command summary")
struct GhCommandSummaryTests {

    @Test func classifiesPullRequestActions() {
        let create = GhCommandSummary.classify(argv: ["pr", "create", "--title", "Fix the bug"])
        #expect(create?.kind == "pr.create")
        #expect(create?.label == "Open PR: Fix the bug")
        #expect(create?.isMutating == true)
        #expect(create?.isMerge == false)

        // No title → a generic label.
        #expect(GhCommandSummary.classify(argv: ["pr", "create"])?.label == "Open a pull request")

        let merge = GhCommandSummary.classify(argv: ["pr", "merge", "42", "--squash"])
        #expect(merge?.kind == "pr.merge")
        #expect(merge?.label == "Merge pull request #42")
        #expect(merge?.isMerge == true)

        #expect(GhCommandSummary.classify(argv: ["pr", "close", "7"])?.label == "Close pull request #7")
    }

    @Test func dropsReadOnlyCommands() {
        // Reads within an actionable noun classify to nil.
        #expect(GhCommandSummary.classify(argv: ["pr", "view", "42"]) == nil)
        #expect(GhCommandSummary.classify(argv: ["pr", "list"]) == nil)
        #expect(GhCommandSummary.classify(argv: ["issue", "status"]) == nil)
        #expect(GhCommandSummary.classify(argv: ["repo", "view"]) == nil)
        // Nouns we don't model at all.
        #expect(GhCommandSummary.classify(argv: ["auth", "status"]) == nil)
        #expect(GhCommandSummary.classify(argv: []) == nil)
    }

    @Test func classifiesReleaseAndRepoActions() {
        let release = GhCommandSummary.classify(argv: ["release", "create", "v1.2.0", "--notes", "x"])
        #expect(release?.kind == "release.create")
        #expect(release?.label == "Create release v1.2.0")

        let del = GhCommandSummary.classify(argv: ["repo", "delete", "me/old-repo", "--yes"])
        #expect(del?.kind == "repo.delete")
        #expect(del?.label == "Delete repository me/old-repo")

        // repo clone is a read/local op git already covers → nil.
        #expect(GhCommandSummary.classify(argv: ["repo", "clone", "me/x"]) == nil)
    }

    @Test func classifiesApiByMethod() {
        // A bare api call is a GET (read) → nil.
        #expect(GhCommandSummary.classify(argv: ["api", "/repos/me/x"]) == nil)

        // An explicit write method is mutating.
        let post = GhCommandSummary.classify(argv: ["api", "-X", "POST", "/repos/me/x/issues"])
        #expect(post?.kind == "api")
        #expect(post?.label == "GitHub API POST /repos/me/x/issues")
        #expect(post?.isMutating == true)

        // A field flag forces a POST even without -X.
        #expect(GhCommandSummary.classify(argv: ["api", "/x", "-f", "a=b"])?.kind == "api")
        #expect(GhCommandSummary.classify(argv: ["api", "/x", "-f", "a=b"])?.label == "GitHub API POST /x")
    }

    @Test func toleratesLeadingGhTokenAndGlobalFlags() {
        // A leading `gh` (or absolute path) and pre-command global flags are skipped.
        #expect(GhCommandSummary.classify(argv: ["gh", "pr", "merge", "3"])?.kind == "pr.merge")
        #expect(GhCommandSummary.classify(argv: ["/usr/bin/gh", "pr", "merge", "3"])?.kind == "pr.merge")
    }
}
