import unittest
import os
import strutils

# Import all public symbols from graft module
from ../src/nip/graft import GraftError, GraftAuditLog, calculateBlake2b, archiveExists, reuseExistingArchive, storeArchiveHash, parseVersionFromFilename, detectPackageVersion

suite "BLAKE2b Grafting Tests":

  setup:
    # Create test directories
    createDir("/tmp/test_nexusos/Programs")
    createDir("/tmp/test_nexusos/cache")

  teardown:
    # Clean up test directories
    if dirExists("/tmp/test_nexusos"):
      removeDir("/tmp/test_nexusos")

  test "calculateBlake2b should calculate correct hash":
    # Create a test file with known content
    let testFile = "/tmp/test_file.txt"
    let testContent = "Hello, NexusOS!"
    writeFile(testFile, testContent)

    # Calculate hash
    let hash = calculateBlake2b(testFile)

    # Verify hash format
    check hash.startsWith("blake2b-")
    check hash.len > 10  # Should be a reasonable length

    # Calculate same hash again - should be identical
    let hash2 = calculateBlake2b(testFile)
    check hash == hash2

    # Clean up
    removeFile(testFile)

  test "calculateBlake2b should handle file read errors":
    expect(GraftError):
      discard calculateBlake2b("/nonexistent/file.txt")

  test "archiveExists should detect existing archives":
    let cacheDir = "/tmp/test_nexusos/cache"
    let testHash = "blake2b-testhash123"

    # Initially should not exist
    check not archiveExists(cacheDir, testHash)

    # Create hash file
    let hashFile = joinPath(cacheDir, testHash & ".hash")
    writeFile(hashFile, "/path/to/archive.pkg.tar.zst")

    # Now should exist
    check archiveExists(cacheDir, testHash)

  test "storeArchiveHash and reuseExistingArchive should work together":
    let cacheDir = "/tmp/test_nexusos/cache"
    let testHash = "blake2b-testhash456"
    let archivePath = "/path/to/test/archive.pkg.tar.zst"

    # Store hash mapping
    storeArchiveHash(cacheDir, archivePath, testHash)

    # Should be able to retrieve it
    check archiveExists(cacheDir, testHash)
    let retrievedPath = reuseExistingArchive(cacheDir, testHash)
    check retrievedPath == archivePath

  test "reuseExistingArchive should handle missing hash files":
    let cacheDir = "/tmp/test_nexusos/cache"
    let nonexistentHash = "blake2b-nonexistent"

    expect(GraftError):
      discard reuseExistingArchive(cacheDir, nonexistentHash)

  test "parseVersionFromFilename should parse pacman filenames correctly":
    # Test typical pacman filename
    check parseVersionFromFilename("neofetch-7.1.0-2-any.pkg.tar.zst") == "7.1.0-2"
    check parseVersionFromFilename("vim-9.0.1000-1-x86_64.pkg.tar.xz") == "9.0.1000-1"
    check parseVersionFromFilename("simple-1.0-any.pkg.tar.zst") == "1.0"

    # Test edge cases
    check parseVersionFromFilename("invalid-filename") == "unknown"
    check parseVersionFromFilename("") == "unknown"

  test "detectPackageVersion should handle command failures gracefully":
    # Test with a package that definitely doesn't exist
    let version = detectPackageVersion("nonexistent-package-xyz123")
    check version == "latest"  # Should fallback to "latest"

  test "GraftAuditLog should contain all required fields":
    let auditLog = GraftAuditLog(
      timestamp: "2024-01-01T12:00:00+00:00",
      source: "pacman",
      packageName: "test-package",
      version: "1.0.0",
      downloadedFilename: "test-package-1.0.0-any.pkg.tar.zst",
      blake2bHash: "blake2b-testhash",
      hashAlgorithm: "blake2b",
      sourceOutput: "test output",
      archiveSize: 1024,
      extractionTime: 0.5,
      fileCount: 10,
      deduplicationStatus: "New",
      originalArchivePath: "/path/to/archive"
    )

    # Verify all fields are accessible
    check auditLog.timestamp == "2024-01-01T12:00:00+00:00"
    check auditLog.source == "pacman"
    check auditLog.packageName == "test-package"
    check auditLog.version == "1.0.0"
    check auditLog.downloadedFilename == "test-package-1.0.0-any.pkg.tar.zst"
    check auditLog.blake2bHash == "blake2b-testhash"
    check auditLog.hashAlgorithm == "blake2b"
    check auditLog.sourceOutput == "test output"
    check auditLog.archiveSize == 1024
    check auditLog.extractionTime == 0.5
    check auditLog.fileCount == 10
    check auditLog.deduplicationStatus == "New"
    check auditLog.originalArchivePath == "/path/to/archive"

when isMainModule:
  # Run the tests
  echo "Running BLAKE2b Grafting Tests..."
