## Unit Tests for Frozen Adapter
##
## Tests for the frozen adapter implementation which handles
## pre-built binary sources like Nix and Arch Linux.

import std/[unittest, options, strutils, tables]
import ../src/nip/resolver/frozen_adapter
import ../src/nip/resolver/source_adapter
import ../src/nip/resolver/variant_types

suite "Frozen Adapter Tests":
  
  test "Create frozen adapter":
    ## Test basic adapter creation
    
    let adapter = newFrozenAdapter("test-frozen", priority = 100)
    
    check adapter.name == "test-frozen"
    check adapter.class == Frozen
    check adapter.priority == 100
    # Empty table check - no packages added yet
  
  test "Add package to frozen adapter":
    ## Test adding packages with variants
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[profile]
    )
    
    adapter.addPackage(metadata)
    
    check adapter.packages.hasKey("firefox")
    check adapter.packages["firefox"].len == 1
    check adapter.packages["firefox"][0].version == "120.0"
  
  test "canSatisfy: Package unavailable":
    ## Test that unavailable packages are detected
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let demand = VariantDemand(
      packageName: "nonexistent",
      variantProfile: profile,
      optional: false
    )
    
    let availability = adapter.canSatisfy(demand)
    
    check availability == Unavailable
  
  test "canSatisfy: Exact variant match":
    ## Test that exact variant matches are detected
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[profile]
    )
    
    adapter.addPackage(metadata)
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: profile,
      optional: false
    )
    
    let availability = adapter.canSatisfy(demand)
    
    check availability == Available
  
  test "canSatisfy: Wrong variant":
    ## Test that variant mismatches are detected
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var availableProfile = newVariantProfile()
    availableProfile.addFlag("graphics", "wayland")
    availableProfile.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[availableProfile]
    )
    
    adapter.addPackage(metadata)
    
    var demandProfile = newVariantProfile()
    demandProfile.addFlag("graphics", "x11")
    demandProfile.calculateHash()
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: demandProfile,
      optional: false
    )
    
    let availability = adapter.canSatisfy(demand)
    
    check availability == WrongVariant
  
  test "canSatisfy: Multiple variants, one matches":
    ## Test that adapter finds matching variant among multiple options
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile1 = newVariantProfile()
    profile1.addFlag("graphics", "wayland")
    profile1.calculateHash()
    
    var profile2 = newVariantProfile()
    profile2.addFlag("graphics", "x11")
    profile2.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[profile1, profile2]
    )
    
    adapter.addPackage(metadata)
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: profile2,
      optional: false
    )
    
    let availability = adapter.canSatisfy(demand)
    
    check availability == Available
  
  test "getVariant: Returns metadata for matching variant":
    ## Test that getVariant returns correct metadata
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[profile],
      sourceHash = "abc123"
    )
    
    adapter.addPackage(metadata)
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: profile,
      optional: false
    )
    
    let result = adapter.getVariant(demand)
    
    check result.isSome
    check result.get.name == "firefox"
    check result.get.version == "120.0"
    check result.get.sourceHash == "abc123"
  
  test "getVariant: Returns none for unavailable package":
    ## Test that getVariant returns none for missing packages
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let demand = VariantDemand(
      packageName: "nonexistent",
      variantProfile: profile,
      optional: false
    )
    
    let result = adapter.getVariant(demand)
    
    check result.isNone
  
  test "getVariant: Returns none for wrong variant":
    ## Test that getVariant returns none for variant mismatch
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var availableProfile = newVariantProfile()
    availableProfile.addFlag("graphics", "wayland")
    availableProfile.calculateHash()
    
    let metadata = newPackageMetadata(
      name = "firefox",
      version = "120.0",
      variants = @[availableProfile]
    )
    
    adapter.addPackage(metadata)
    
    var demandProfile = newVariantProfile()
    demandProfile.addFlag("graphics", "x11")
    demandProfile.calculateHash()
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: demandProfile,
      optional: false
    )
    
    let result = adapter.getVariant(demand)
    
    check result.isNone
  
  test "synthesize: Always fails for frozen adapter":
    ## Test that frozen adapters cannot synthesize packages
    
    let adapter = newFrozenAdapter("test-frozen")
    
    var profile = newVariantProfile()
    profile.addFlag("graphics", "wayland")
    profile.calculateHash()
    
    let demand = VariantDemand(
      packageName: "firefox",
      variantProfile: profile,
      optional: false
    )
    
    let result = adapter.synthesize(demand)
    
    check not result.isOk
    check result.error.exitCode == 1
    check "frozen source" in result.error.message.toLowerAscii()

