## test_variant_migration.nim
## Tests for variant migration utilities (Task 15)

import std/[unittest, tables, os, strutils]
import ../src/nimpak/variant_migration
import ../src/nimpak/variant_domains
import ../src/nimpak/config

suite "Variant Migration Utilities":

  test "Detect legacy category":
    check isLegacyCategory("gui") == true
    check isLegacyCategory("gaming") == true
    check isLegacyCategory("optimization") == true
    check isLegacyCategory("invalid") == false

  test "Map legacy category to domain":
    check mapLegacyCategoryToDomain("gui") == "graphics"
    check mapLegacyCategoryToDomain("gaming") == "graphics"
    check mapLegacyCategoryToDomain("container") == "integration"
    check mapLegacyCategoryToDomain("optimization") == "optimization"
    check mapLegacyCategoryToDomain("init") == "init"

  test "Translate single legacy flag":
    let (domain1, flag1, success1) = translateLegacyFlag("wayland", "gui")
    check success1 == true
    check domain1 == "graphics"
    check flag1 == "wayland"

    let (domain2, flag2, success2) = translateLegacyFlag("lto", "optimization")
    check success2 == true
    check domain2 == "optimization"
    check flag2 == "lto"

  test "Skip special categories in translation":
    let (_, _, success1) = translateLegacyFlag("something", "nexus-fleet")
    check success1 == false

    let (_, _, success2) = translateLegacyFlag("something", "nexus-bootstrap")
    check success2 == false

  test "Translate flag string - legacy to new":
    check translateFlagString("gui/wayland") == "+graphics=wayland"
    check translateFlagString("optimization/lto") == "+optimization=lto"
    check translateFlagString("gaming/vulkan") == "+graphics=vulkan"
    check translateFlagString("container/docker") == "+integration=docker"

  test "Translate flag string - already new syntax":
    check translateFlagString("+graphics=wayland") == "+graphics=wayland"
    check translateFlagString("+optimization=lto") == "+optimization=lto"

  test "Detect legacy flag string":
    check isLegacyFlagString("gui/wayland") == true
    check isLegacyFlagString("optimization/lto") == true
    check isLegacyFlagString("+graphics=wayland") == false
    check isLegacyFlagString("+optimization=lto") == false

  test "Translate multiple legacy flags":
    let flags = @[
      UseFlag(name: "wayland", enabled: true, category: "gui"),
      UseFlag(name: "lto", enabled: true, category: "optimization"),
      UseFlag(name: "dinit", enabled: true, category: "init")
    ]

    let result = translateLegacyFlags(flags)

    check result.success == true
    check result.translatedFlags.hasKey("graphics")
    check result.translatedFlags.hasKey("optimization")
    check result.translatedFlags.hasKey("init")
    check "wayland" in result.translatedFlags["graphics"]
    check "lto" in result.translatedFlags["optimization"]
    check "dinit" in result.translatedFlags["init"]

  test "Skip disabled flags in translation":
    let flags = @[
      UseFlag(name: "wayland", enabled: true, category: "gui"),
      UseFlag(name: "x11", enabled: false, category: "gui")
    ]

    let result = translateLegacyFlags(flags)

    check result.translatedFlags.hasKey("graphics")
    check "wayland" in result.translatedFlags["graphics"]
    check "x11" notin result.translatedFlags["graphics"]

  test "Generate migration warning":
    let flag = LegacyFlagInfo(
      name: "wayland",
      category: "gui",
      enabled: true,
      suggestedDomain: "graphics",
      suggestedFlag: "wayland"
    )

    let warning = generateMigrationWarning(flag)
    check "deprecated" in warning.toLower()
    check "graphics" in warning
    check "wayland" in warning

  test "Generate migration summary":
    var result = MigrationResult(
      success: true,
      translatedFlags: initTable[string, seq[string]](),
      warnings: @["Warning 1"],
      errors: @[],
      skippedFlags: @["nexus-fleet/something"]
    )

    result.translatedFlags["graphics"] = @["wayland", "vulkan"]
    result.translatedFlags["optimization"] = @["lto"]

    let summary = generateMigrationSummary(result)

    check "Translated Flags" in summary
    check "graphics" in summary
    check "wayland" in summary
    check "Skipped Flags" in summary
    check "Warnings" in summary

  test "Migrate config file":
    let testConfig = """# Test config
gui/wayland
optimization/lto
# Comment
init/dinit
"""

    let tempFile = getTempDir() / "test-migration-config.conf"
    writeFile(tempFile, testConfig)

    let (success, message) = migrateConfigFile(tempFile)

    check success == true
    check "Migrated" in message or "migrated" in message.toLower()

    # Check migrated content
    let migrated = readFile(tempFile)
    check "+graphics=wayland" in migrated
    check "+optimization=lto" in migrated
    check "+init=dinit" in migrated
    check "gui/wayland" notin migrated

    removeFile(tempFile)

  test "Migrate config file - no legacy flags":
    let testConfig = """+graphics=wayland
+optimization=lto
"""

    let tempFile = getTempDir() / "test-migration-modern.conf"
    writeFile(tempFile, testConfig)

    let (success, message) = migrateConfigFile(tempFile)

    check success == true
    check "No legacy flags" in message or "no legacy" in message.toLower()

    removeFile(tempFile)

  test "Migrate config file to different output":
    let testConfig = """gui/wayland
optimization/lto
"""

    let inputFile = getTempDir() / "test-migration-input.conf"
    let outputFile = getTempDir() / "test-migration-output.conf"

    writeFile(inputFile, testConfig)

    let (success, _) = migrateConfigFile(inputFile, outputFile)

    check success == true
    check fileExists(outputFile)

    let migrated = readFile(outputFile)
    check "+graphics=wayland" in migrated
    check "+optimization=lto" in migrated

    # Original should be unchanged
    let original = readFile(inputFile)
    check "gui/wayland" in original

    removeFile(inputFile)
    removeFile(outputFile)

  test "Create migration backup":
    let testFile = getTempDir() / "test-backup.conf"
    writeFile(testFile, "test content")

    let backed = createMigrationBackup(testFile)
    check backed == true
    check fileExists(testFile & ".backup")

    let backupContent = readFile(testFile & ".backup")
    check backupContent == "test content"

    removeFile(testFile)
    removeFile(testFile & ".backup")

  test "Suggest domain flags":
    let legacyFlags = @["gui/wayland", "optimization/lto", "+graphics=x11"]
    let suggested = suggestDomainFlags(legacyFlags)

    check suggested.len == 3
    check "+graphics=wayland" in suggested
    check "+optimization=lto" in suggested
    check "+graphics=x11" in suggested

  test "Detect legacy flags in UseFlag list":
    let flags = @[
      UseFlag(name: "wayland", enabled: true, category: "gui"),
      UseFlag(name: "lto", enabled: true, category: "optimization")
    ]

    let detected = detectLegacyFlags(flags)

    check detected.len == 2
    check detected[0].category == "gui"
    check detected[0].suggestedDomain == "graphics"
    check detected[1].category == "optimization"
    check detected[1].suggestedDomain == "optimization"

  test "Get all legacy categories":
    let categories = getLegacyCategories()

    check categories.len > 0
    check "gui" in categories
    check "gaming" in categories
    check "optimization" in categories
    check "init" in categories

  test "Preserve comments during migration":
    let testConfig = """# Header comment
gui/wayland
# Middle comment
optimization/lto
# Footer comment
"""

    let tempFile = getTempDir() / "test-migration-comments.conf"
    writeFile(tempFile, testConfig)

    let (success, _) = migrateConfigFile(tempFile)
    check success == true

    let migrated = readFile(tempFile)
    check "# Header comment" in migrated
    check "# Middle comment" in migrated
    check "# Footer comment" in migrated

    removeFile(tempFile)
