## test_variant_cli.nim
## Tests for variant CLI commands (diff and explain)

import std/[unittest, tables, strutils]
import ../src/nimpak/variant_domains
import ../src/nimpak/variant_compiler

suite "Variant CLI Commands - Domain and Compiler Rules":

  test "Variant explain command validates domain existence":
    # Test that SEMANTIC_DOMAINS contains expected domains
    check SEMANTIC_DOMAINS.hasKey("init")
    check SEMANTIC_DOMAINS.hasKey("graphics")
    check SEMANTIC_DOMAINS.hasKey("security")
    check SEMANTIC_DOMAINS.hasKey("optimization")
    check SEMANTIC_DOMAINS.hasKey("runtime")

  test "Variant explain command shows domain description":
    # Verify domain info is accessible
    let initDomain = SEMANTIC_DOMAINS["init"]
    check initDomain.description.len > 0
    check initDomain.options.len > 0

  test "Variant explain command shows flag options":
    # Verify flag options are available
    let securityDomain = SEMANTIC_DOMAINS["security"]
    check "pie" in securityDomain.options
    check "relro" in securityDomain.options
    check "hardened" in securityDomain.options

  test "Variant explain command shows compiler flag effects":
    # Verify compiler flag rules exist
    check COMPILER_FLAG_RULES.hasKey("security")
    check COMPILER_FLAG_RULES.hasKey("optimization")

    let securityRules = COMPILER_FLAG_RULES["security"]
    check securityRules.hasKey("pie")
    check securityRules.hasKey("relro")

    let pieRule = securityRules["pie"]
    check pieRule.cflags.len > 0
    check pieRule.ldflags.len > 0

  test "Variant explain command handles invalid domain":
    # Test that invalid domain is detected
    check not SEMANTIC_DOMAINS.hasKey("invalid-domain")

  test "Variant explain command handles invalid flag":
    # Test that invalid flag in valid domain is detected
    let securityDomain = SEMANTIC_DOMAINS["security"]
    check "invalid-flag" notin securityDomain.options

  test "Variant explain command shows exclusive domain info":
    # Test exclusive domain detection
    let initDomain = SEMANTIC_DOMAINS["init"]
    check initDomain.exclusive == true

    let securityDomain = SEMANTIC_DOMAINS["security"]
    check securityDomain.exclusive == false

  test "Variant explain command shows default values":
    # Test default value display
    let initDomain = SEMANTIC_DOMAINS["init"]
    check initDomain.default.len > 0
    check initDomain.default in initDomain.options

  test "Variant diff logic - domain comparison":
    # Test the logic that would be used in diff command
    let domains1 = {
      "init": @["dinit"],
      "graphics": @["wayland"],
      "security": @["pie", "relro"]
    }.toTable

    let domains2 = {
      "init": @["systemd"],
      "graphics": @["wayland"],
      "security": @["hardened"],
      "optimization": @["lto"]
    }.toTable

    # Check for added domains
    var addedDomains: seq[string] = @[]
    for domain in domains2.keys:
      if not domains1.hasKey(domain):
        addedDomains.add(domain)
    check "optimization" in addedDomains

    # Check for removed domains (none in this case)
    var removedDomains: seq[string] = @[]
    for domain in domains1.keys:
      if not domains2.hasKey(domain):
        removedDomains.add(domain)
    check removedDomains.len == 0

    # Check for changed domains
    var changedDomains: seq[string] = @[]
    for domain in domains1.keys:
      if domains2.hasKey(domain):
        if domains1[domain] != domains2[domain]:
          changedDomains.add(domain)
    check "init" in changedDomains
    check "security" in changedDomains
    check "graphics" notin changedDomains  # unchanged

  test "Compiler flag rule structure":
    # Verify the structure of compiler flag rules
    let optimizationRules = COMPILER_FLAG_RULES["optimization"]
    check optimizationRules.hasKey("lto")
    check optimizationRules.hasKey("march-native")
    check optimizationRules.hasKey("pgo")

    let ltoRule = optimizationRules["lto"]
    check ltoRule.condition == "lto"
    check "lto" in ltoRule.cflags
    check "lto" in ltoRule.ldflags
