//
//  GitignoreParserTests.swift
//  oAITests
//
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
// Copyright (C) 2026 Rune Olsen

import Testing
@testable import Confab

@Suite("GitignoreParser")
struct GitignoreParserTests {

    private func parser(for content: String) -> GitignoreParser {
        var parser = GitignoreParser(rootPath: "/tmp/fake-root")
        parser.parseContent(content)
        return parser
    }

    @Test("Simple extension wildcard matches at any depth")
    func extensionWildcard() {
        let p = parser(for: "*.log")
        #expect(p.isIgnored("debug.log"))
        #expect(p.isIgnored("nested/debug.log"))
        #expect(!p.isIgnored("debug.txt"))
    }

    @Test("Directory pattern matches the directory and everything under it")
    func directoryPattern() {
        let p = parser(for: "build/")
        #expect(p.isIgnored("build"))
        #expect(p.isIgnored("build/output.txt"))
        #expect(p.isIgnored("foo/build/output.txt"))
        #expect(!p.isIgnored("rebuild"))
    }

    @Test("Path-anchored pattern only matches that exact relative path, not nested occurrences")
    func pathAnchoredWildcard() {
        let p = parser(for: "src/*.tmp")
        #expect(p.isIgnored("src/foo.tmp"))
        #expect(!p.isIgnored("other/src/foo.tmp"))
        #expect(!p.isIgnored("src/sub/foo.tmp"))
    }

    @Test("Double-star matches across any number of intermediate directories")
    func doubleStarPattern() {
        let p = parser(for: "**/logs")
        #expect(p.isIgnored("logs"))
        #expect(p.isIgnored("a/logs"))
        #expect(p.isIgnored("a/b/logs"))
        #expect(p.isIgnored("a/logs/file.txt"))
        #expect(!p.isIgnored("logsfile"))
    }

    @Test("Negation un-ignores a path matched by an earlier rule")
    func negation() {
        let p = parser(for: "*.log\n!important.log")
        #expect(p.isIgnored("debug.log"))
        #expect(!p.isIgnored("important.log"))
    }

    @Test("Comments and blank lines are skipped, not treated as patterns")
    func commentsAndBlankLines() {
        let p = parser(for: "# a comment\n\n*.log\n   \n")
        #expect(p.isIgnored("x.log"))
        #expect(!p.isIgnored("# a comment"))
    }

    @Test("Leading slash still matches (root-anchoring is not enforced by this implementation)")
    func leadingSlashPattern() {
        // Documents actual current behavior: the leading "/" is stripped without
        // truly restricting the match to the root level, unlike real git.
        let p = parser(for: "/dist")
        #expect(p.isIgnored("dist"))
        #expect(p.isIgnored("dist/file.txt"))
    }

    @Test("No rules means nothing is ignored")
    func noRules() {
        let p = parser(for: "")
        #expect(!p.isIgnored("anything.txt"))
    }
}
