## tests/test_cli_commands.nim
## Unit tests for CLI command functionality
##
## Tests all CLI commands, output formatting, error handling,
## and user interface functionality.

import std/[unittest, os, json, strutils]
import ../src/nimpak/cli/[commands, config_commands, cell_commands]

suite "CLI Commands Tests":

  setup:
    # Create temporary test directory
    let testDir = getTempDir() / "nip_test_cli"
    createDir(testDir)

  teardown:
    # Clean up test directory
    let testDir = getTempDir() / "nip_test_cli"
    if dirExists(testDir):
      removeDir(testDir)

  test "Install command basic functionality":
    let result = installCommand("htop", "stable", "", false)

    check result.success == true
    check "htop" in result.message
    check result.data != nil

  test "Remove command functionality":
    # First install, then remove
    discard installCommand("vim", "stable", "", false)
    let result = removeCommand("vim")

    check result.success == true
    check "vim" in result.message

  test "Search command functionality":
    let result = searchCommand("editor")

    check result.success == true
    check result.data != nil

    # Should find some packages
    if result.data.hasKey("packages"):
      let packages = result.data["packages"]
      check packages.len > 0

  test "List command functionality":
    # Install some packages first
    discard installCommand("htop", "stable", "", false)
    discard installCommand("vim", "stable", "", false)

    let result = listCommand(true)

    check result.success == true
    check result.data != nil

  test "Info command functionality":
    let result = infoCommand("htop")

    check result.success == true
    check result.data != nil
    check result.data["name"].getStr() == "htop"

  test "Update command functionality":
    let result = updateCommand()

    check result.success == true
    check "updated" in result.message.toLower()

  test "Upgrade command functionality":
    let result = upgradeCommand()

    check result.success == true

suite "Configuration CLI Tests":

  test "Config show command":
    let result = configShowCommand()

    check result.success == true
    check result.data != nil

  test "Config init command":
    let result = configInitCommand()

    check result.success == true
    check "initialized" in result.message.toLower()

  test "Config validate command":
    let result = configValidateCommand()

    check result.success == true

  test "Config set command":
    let result = configSetCommand("default-stream", "testing")

    check result.success == true
    check "testing" in result.message

  test "Config get command":
    # First set a value
    discard configSetCommand("log-level", "debug")

    let result = configGetCommand("log-level")

    check result.success == true

  test "Config set invalid key":
    let result = configSetCommand("invalid-key", "value")

    check result.success == false
    check "unknown" in result.message.toLower()

  test "Config set invalid value":
    let result = configSetCommand("trust-level", "invalid")

    check result.success == false
    check "invalid" in result.message.toLower()

suite "Stream Management CLI Tests":

  test "Stream list command":
    let result = streamListCommand(false)

    check result.success == true
    check result.data != nil

    if result.data.hasKey("streams"):
      let streams = result.data["streams"]
      check streams.len > 0

  test "Stream list all command":
    let result = streamListCommand(true)

    check result.success == true
    check result.data != nil

  test "Stream switch command":
    let result = streamSwitchCommand("testing")

    check result.success == true
    check "testing" in result.message

  test "Stream switch invalid":
    let result = streamSwitchCommand("nonexistent")

    check result.success == false

  test "Stream info command":
    let result = streamInfoCommand("stable")

    check result.success == true
    check result.data != nil
    check result.data["name"].getStr() == "stable"

  test "Stream info invalid":
    let result = streamInfoCommand("nonexistent")

    check result.success == false

  test "Stream stats command":
    let result = streamStatsCommand()

    check result.success == true
    check result.data != nil

suite "NipCells CLI Tests":

  test "Cell create command":
    let result = cellCreateCommand("test-cell", "user", "standard", "Test cell")

    check result.success == true
    check "test-cell" in result.message
    check result.data != nil

  test "Cell create with invalid type":
    let result = cellCreateCommand("test-cell", "invalid", "standard", "")

    check result.success == false
    check "invalid" in result.message.toLower()

  test "Cell create with invalid isolation":
    let result = cellCreateCommand("test-cell", "user", "invalid", "")

    check result.success == false
    check "invalid" in result.message.toLower()

  test "Cell list command":
    # Create some cells first
    discard cellCreateCommand("cell1", "user", "standard", "")
    discard cellCreateCommand("cell2", "development", "strict", "")

    let result = cellListCommand(false)

    check result.success == true
    check result.data != nil

  test "Cell activate command":
    # Create cell first
    discard cellCreateCommand("activate-test", "user", "standard", "")

    let result = cellActivateCommand("activate-test")

    check result.success == true
    check "activate-test" in result.message

  test "Cell activate nonexistent":
    let result = cellActivateCommand("nonexistent")

    check result.success == false

  test "Cell delete command":
    # Create cell first
    discard cellCreateCommand("delete-test", "user", "standard", "")

    let result = cellDeleteCommand("delete-test", true)

    check result.success == true
    check "delete-test" in result.message

  test "Cell info command":
    # Create cell first
    discard cellCreateCommand("info-test", "user", "standard", "")

    let result = cellInfoCommand("info-test")

    check result.success == true
    check result.data != nil

  test "Cell status command":
    let result = cellStatusCommand()

    check result.success == true
    check result.data != nil

  test "Cell comparison command":
    let result = cellComparisonCommand()

    check result.success == true
    check result.data != nil

suite "CLI Error Handling Tests":

  test "Install nonexistent package":
    let result = installCommand("nonexistent-package-12345", "stable", "", false)

    check result.success == false
    check "not found" in result.message.toLower()

  test "Remove nonexistent package":
    let result = removeCommand("nonexistent-package-12345")

    check result.success == false
    check "not installed" in result.message.toLower()

  test "Info nonexistent package":
    let result = infoCommand("nonexistent-package-12345")

    check result.success == true  # Should return mock data
    check result.data != nil

  test "Empty search query":
    let result = searchCommand("")

    check result.success == false

suite "CLI Output Format Tests":

  test "Command result structure":
    let result = installCommand("htop", "stable", "", false)

    # Check that result has proper structure
    check result.success in [true, false]
    check result.message.len > 0
    check result.data != nil

  test "JSON output compatibility":
    let result = configShowCommand()

    if result.success and result.data != nil:
      # Should be valid JSON structure
      check result.data.kind == JObject

  test "Error message format":
    let result = installCommand("", "stable", "", false)  # Empty package name

    check result.success == false
    check result.message.len > 0
    check "usage" in result.message.toLower() or "error" in result.message.toLower()

when isMainModule:
  echo "🧪 Running CLI Commands Tests..."
  echo "Testing all CLI functionality and user interface..."

  # This will run all the test suites
  discard