## test_recipe_manager.nim
## Unit tests for recipe manager

import std/[unittest, options, os, strutils]
import ../src/nimpak/build/[recipe_manager, recipe_parser, bootstrap]

suite "Recipe Manager Tests":

  setup:
    # Use a test cache directory
    let testCache = getTempDir() / "nip-test-recipes"
    let rm = newRecipeManager(cacheDir = testCache)

  teardown:
    # Clean up test cache
    if dirExists(testCache):
      removeDir(testCache)

  test "Create recipe manager":
    check rm != nil
    check rm.localCache.len > 0
    check rm.repoUrl.len > 0

  test "Get recipe path":
    let nixPath = rm.getRecipePath(bttNix)
    check "nix" in nixPath
    check "minimal-nix.kdl" in nixPath

    let pkgsrcPath = rm.getRecipePath(bttPkgsrc)
    check "pkgsrc" in pkgsrcPath

    let gentooPath = rm.getRecipePath(bttGentoo)
    check "gentoo" in gentooPath

  test "Check if repo is cloned":
    check not rm.isRepoCloned()

  test "List available recipes (no repo)":
    let recipes = rm.listAvailableRecipes()
    # Should be empty if repo not cloned
    check recipes.len == 0

  test "Clear cache":
    rm.clearCache()
    # Just check it doesn't crash
    check true

  test "Needs update":
    # Should need update if never updated
    check rm.needsUpdate()

  test "Get cache stats":
    let stats = rm.getCacheStats()
    check stats.cached == 0
    check stats.total == 3
    check stats.lastUpdate == "never"

  test "Load recipe from local file":
    # Create a test recipe file
    let testRecipeDir = rm.localCache / "nix"
    createDir(testRecipeDir)

    let testRecipe = """
recipe "test-nix" {
    version "1.0.0"
    tool-type "nix"

    platform arch="x86_64" os="linux" {
        binary "test-binary" {
            url "https://example.com/test"
            checksum "blake2b-test"
            size 1000
        }
    }

    install {
        script "install.sh"
    }
}
"""

    writeFile(rm.getRecipePath(bttNix), testRecipe)

    # Create .git directory to simulate cloned repo
    createDir(rm.localCache / ".git")

    let recipeOpt = rm.loadRecipe(bttNix)
    check recipeOpt.isSome

    if recipeOpt.isSome:
      let recipe = recipeOpt.get()
      check recipe.name == "test-nix"
      check recipe.version == "1.0.0"
      check recipe.toolType == "nix"

  test "Get recipe version":
    # Create a test recipe
    let testRecipeDir = rm.localCache / "pkgsrc"
    createDir(testRecipeDir)

    let testRecipe = """
recipe "test-pkgsrc" {
    version "2.0.0"
    tool-type "pkgsrc"

    platform arch="x86_64" os="linux" {
        binary "test" {
            url "https://example.com/test"
            checksum "blake2b-test"
            size 1000
        }
    }

    install {
        script "install.sh"
    }
}
"""

    writeFile(rm.getRecipePath(bttPkgsrc), testRecipe)
    createDir(rm.localCache / ".git")

    let versionOpt = rm.getRecipeVersion(bttPkgsrc)
    check versionOpt.isSome

    if versionOpt.isSome:
      check versionOpt.get() == "2.0.0"

  test "Get recipe info":
    # Create a test recipe
    let testRecipeDir = rm.localCache / "gentoo"
    createDir(testRecipeDir)

    let testRecipe = """
recipe "test-gentoo" {
    version "3.0.0"
    description "Test Gentoo recipe"
    tool-type "gentoo"

    platform arch="x86_64" os="linux" {
        binary "test" {
            url "https://example.com/test"
            checksum "blake2b-test"
            size 1000
        }
    }

    install {
        script "install.sh"
    }
}
"""

    writeFile(rm.getRecipePath(bttGentoo), testRecipe)
    createDir(rm.localCache / ".git")

    let infoOpt = rm.getRecipeInfo(bttGentoo)
    check infoOpt.isSome

    if infoOpt.isSome:
      let info = infoOpt.get()
      check info.name == "test-gentoo"
      check info.version == "3.0.0"
      check info.description == "Test Gentoo recipe"

  test "Select platform for recipe":
    # Create a test recipe with multiple platforms
    let testRecipeDir = rm.localCache / "nix"
    createDir(testRecipeDir)

    let testRecipe = """
recipe "multi-platform" {
    version "1.0.0"
    tool-type "nix"

    platform arch="x86_64" os="linux" {
        binary "test-x64" {
            url "https://example.com/test-x64"
            checksum "blake2b-x64"
            size 1000
        }
    }

    platform arch="aarch64" os="linux" {
        binary "test-arm" {
            url "https://example.com/test-arm"
            checksum "blake2b-arm"
            size 1000
        }
    }

    install {
        script "install.sh"
    }
}
"""

    writeFile(rm.getRecipePath(bttNix), testRecipe)
    createDir(rm.localCache / ".git")

    let recipeOpt = rm.loadRecipe(bttNix)
    check recipeOpt.isSome

    if recipeOpt.isSome:
      let recipe = recipeOpt.get()
      let platformOpt = rm.selectPlatformForRecipe(recipe)
      check platformOpt.isSome

      # Should select platform matching current system
      if platformOpt.isSome:
        let platform = platformOpt.get()
        check platform.binaries.len > 0

  test "Validate recipe":
    # Create a valid recipe
    let testRecipeDir = rm.localCache / "nix"
    createDir(testRecipeDir)

    let testRecipe = """
recipe "valid" {
    version "1.0.0"
    tool-type "nix"

    platform arch="x86_64" os="linux" {
        binary "test" {
            url "https://example.com/test"
            checksum "blake2b-test"
            size 1000
        }
    }

    install {
        script "install.sh"
    }
}
"""

    writeFile(rm.getRecipePath(bttNix), testRecipe)
    createDir(rm.localCache / ".git")

    let recipeOpt = rm.loadRecipe(bttNix)
    check recipeOpt.isSome

    if recipeOpt.isSome:
      let recipe = recipeOpt.get()
      let (valid, errors) = rm.validateRecipeWithErrors(recipe)
      check valid
      check errors.len == 0
