import unittest, options
import std/[os, tempfiles, strutils]
import ../src/nimpak/adapters/git
import ../src/nimpak/cas

suite "Git Adapter":
  
  test "Parse GitHub URL":
    let result = parseGitUrl("git+https://github.com/nim-lang/Nim.git")
    check result.isOk
    let source = result.value
    check source.kind == GitHub
    check source.owner == "nim-lang"
    check source.repo == "Nim"
    check source.baseUrl == "https://github.com"
    
  test "Parse GitHub Shorthand":
    let result = parseGitUrl("github:NixOS/nixpkgs")
    check result.isOk
    let source = result.value
    check source.kind == GitHub
    check source.owner == "NixOS"
    check source.repo == "nixpkgs"
    
  test "Parse GitLab Shorthand":
    let result = parseGitUrl("gitlab:fdroid/fdroiddata")
    check result.isOk
    let source = result.value
    check source.kind == GitLab
    check source.owner == "fdroid"
    check source.repo == "fdroiddata"
    
  test "Parse URL with Tag Specifier":
    let result = parseGitUrl("github:nim-lang/Nim@v2.0.0")
    check result.isOk
    let source = result.value
    check source.owner == "nim-lang"
    check source.repo == "Nim"
    check source.tagPattern == "v2.0.0"
    
  test "Parse URL with Branch Fragment":
    let result = parseGitUrl("github:nim-lang/Nim#branch=devel")
    check result.isOk
    let source = result.value
    check source.branch == "devel"

suite "Semver Matching":
  
  test "Wildcard matches all":
    check matchesSemver("v1.0.0", "*")
    check matchesSemver("2.5.3", "*")
    check matchesSemver("anything", "*")
    
  test "Prefix wildcard":
    check matchesSemver("v1.2.3", "v1.*")
    check matchesSemver("v1.99.0", "v1.*")
    check not matchesSemver("v2.0.0", "v1.*")
    
  test "Greater than or equal":
    check matchesSemver("2.0.0", ">=1.0.0")
    check matchesSemver("1.0.0", ">=1.0.0")
    check not matchesSemver("0.9.0", ">=1.0.0")
    
  test "Exact match":
    check matchesSemver("v1.2.3", "v1.2.3")
    check matchesSemver("1.2.3", "1.2.3")
    check not matchesSemver("1.2.4", "1.2.3")

suite "Tag Filtering":
  
  test "Filter and sort tags":
    let tags = @[
      GitTag(name: "v1.0.0", commit: "aaa", isRelease: false),
      GitTag(name: "v2.0.0", commit: "bbb", isRelease: false),
      GitTag(name: "v1.5.0", commit: "ccc", isRelease: false),
      GitTag(name: "v3.0.0", commit: "ddd", isRelease: false),
    ]
    
    let filtered = filterTags(tags, "v1.*")
    check filtered.len == 2
    # Should be sorted newest first
    check filtered[0].name == "v1.5.0"
    check filtered[1].name == "v1.0.0"

suite "CAS Ingestion":
  
  test "Ingest local directory to CAS":
    
    # Create temp directories - one for content, one for CAS
    let tempDir = createTempDir("nip_test_", "_ingest")
    let contentDir = tempDir / "content"
    createDir(contentDir)
    defer: removeDir(tempDir)
    
    writeFile(contentDir / "file1.txt", "Hello World")
    writeFile(contentDir / "file2.txt", "Test content")
    createDir(contentDir / "subdir")
    writeFile(contentDir / "subdir" / "nested.txt", "Nested file")
    
    # Initialize CAS in a separate location
    var cas = initCasManager(tempDir / "cas-root")
    
    # Ingest the content directory (not the temp dir itself)
    let result = ingestDirToCas(cas, contentDir, excludeGit = true)
    
    check result.success
    check result.files.len == 3
    check result.casHash.len > 0
    check result.totalSize > 0

  test "Asset pattern matching":
    let release = GitRelease(
      tag: "v1.0.0",
      name: "Release 1.0.0",
      assets: @[
        GitAsset(name: "app-v1.0.0-linux-amd64.tar.gz", url: "http://example.com/a"),
        GitAsset(name: "app-v1.0.0-darwin-arm64.tar.gz", url: "http://example.com/b"),
        GitAsset(name: "app-v1.0.0-windows.zip", url: "http://example.com/c"),
        GitAsset(name: "checksums.txt", url: "http://example.com/d"),
      ]
    )
    
    # Test suffix match
    let tarGz = findAssetByPattern(release, "*.tar.gz")
    check tarGz.isSome
    check tarGz.get().name.endsWith(".tar.gz")
    
    # Test contains match
    let linux = findAssetByPattern(release, "*linux*")
    check linux.isSome
    check "linux" in linux.get().name
    
    # Test exact match
    let checksums = findAssetByPattern(release, "checksums.txt")
    check checksums.isSome
    check checksums.get().name == "checksums.txt"
    
    # Test no match
    let noMatch = findAssetByPattern(release, "*.rpm")
    check noMatch.isNone
