## NimPak CLI - Next-generation package manager for NexusOS
##
## Main entry point for the `nip` command-line tool.
## Provides atomic, reproducible package management with ACUL compliance.

import std/[os, strformat, strutils, posix, tempfiles, asyncdispatch]
import nimpak/cli/[core, commands, dependency_graph, cell_commands, enhanced_search, shell, publish_commands, remote_commands]
import nimpak/cli/help
import nimpak/cli/graft_commands as graft  # Variant system integration
import nimpak/cli/build_commands as build  # Source building with variants
import nimpak/cli/variant_switch  # Variant switching commands
import nimpak/cli/bootstrap_commands  # Build tool bootstrap
import nimpak/variant_migration
import nip/doctor
import nip/cli/resolve_command  # Dependency resolution commands
import nimpak/config
import nip/[manifest_parser, archives, nip_installer, namespace, cas, types]

const
  NimPakVersion = "0.1.0"
  NimPakBanner = """
🌱 NimPak v$1 - Universal Package Manager for NexusOS
   Atomic • Reproducible • ACUL Compliant • 205,000+ Packages
""" % [NimPakVersion]

# ==========================================================================
# Configuration Commands
# ==========================================================================

proc showConfigCommand(): CommandResult =
  ## Show current configuration
  let cfg = loadConfig()
  let isRoot = getuid() == 0
  let userType = if isRoot: "root (system-wide)" else: "user (local)"

  echo "📋 NIP Configuration"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo fmt"Running as: {userType}"
  echo ""
  echo "Directories:"
  echo fmt"  Programs: {cfg.programsDir}"
  echo fmt"  Links:    {cfg.linksDir}"
  echo fmt"  Cache:    {cfg.cacheDir}"
  echo fmt"  Database: {cfg.dbFile}"
  echo ""
  echo "Options:"
  echo fmt"  Auto-symlink:     {cfg.autoSymlink}"
  echo fmt"  Check conflicts:  {cfg.checkConflicts}"
  echo fmt"  Verbose:          {cfg.verbose}"
  echo ""
  echo "Variant System:"
  echo fmt"  Default toolchain: {cfg.defaultToolchain}"
  echo fmt"  Default target:    {cfg.defaultTarget}"
  echo "  Profile paths:"
  for path in cfg.profileSearchPaths:
    echo fmt"    - {path}"

  return successResult("")

proc initConfigCommand(): CommandResult =
  ## Initialize user configuration file (XDG compliant)
  let xdgConfigHome = getEnv("XDG_CONFIG_HOME", getHomeDir() / ".config")
  let configPath = xdgConfigHome / "nip" / "config"

  if fileExists(configPath):
    return errorResult(fmt"Config already exists at: {configPath}")

  if saveExampleConfig(configPath):
    return successResult(fmt"Created config at: {configPath}")
  else:
    return errorResult("Failed to create config file")

proc showConfigPathCommand(): CommandResult =
  ## Show configuration file paths (XDG compliant)
  let xdgConfigHome = getEnv("XDG_CONFIG_HOME", getHomeDir() / ".config")
  let userConfig = xdgConfigHome / "nip" / "config"
  let globalConfig = "/etc/nip/nip.conf"
  let userStatus = if fileExists(userConfig): "✓" else: "(not found)"
  let globalStatus = if fileExists(globalConfig): "✓" else: "(not found)"

  echo "📁 Configuration File Paths (XDG Base Directory)"
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
  echo fmt"User config:   {userConfig} {userStatus}"
  echo fmt"Global config: {globalConfig} {globalStatus}"

  return successResult("")

# ==========================================================================
# Main Command Dispatcher
# =============================================================================

proc dispatchCommand(args: seq[string]): int =
  ## Main command dispatcher with advanced CLI features
  if args.len == 0:
    showMainHelp()
    return 0

  # Parse global options
  let (globalOptions, remainingArgs) = parseGlobalOptions(args)
  discard initCliContext(globalOptions)

  if remainingArgs.len == 0:
    showMainHelp()
    return 0

  let command = remainingArgs[0].toLower()
  let commandArgs = remainingArgs[1..^1]

  var result: CommandResult

  try:
    case command:
    # Core package management commands
    of "install":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip install <package|file.nip> [options]")
      else:
        let target = commandArgs[0]
        if target.endsWith(".nip"):
           # Local NIP installation
           try:
             let extractDir = createTempDir("nip_install_", "")
             defer: removeDir(extractDir)
             extractArchive(target, extractDir)
             
             let manifestPath = extractDir / "manifest.kdl"
             if not fileExists(manifestPath):
                raise newException(ValueError, "Invalid archive: manifest.kdl missing")
                
             var manifest = parseManifest(readFile(manifestPath), NIP, FormatKDL)
             
             let home = getHomeDir()
             let casRoot = home / ".local/share/nexus/cas"
             discard initCasManager(casRoot, casRoot)
             
             # Ingest files into CAS and update manifest hashes
             for i in 0..<manifest.files.len:
                let fileSpec = manifest.files[i]
                let srcPath = extractDir / "files" / fileSpec.path
                if fileExists(srcPath):
                   let content = readFile(srcPath)
                   let entry = storeObject(content, casRoot)
                   # Update hash in manifest to match stored object
                   manifest.files[i].hash = string(entry.hash)
                
             let installer = newNipInstaller(casRoot)
             installer.installNip(manifest)
             
             result = successResult(fmt"Installed {manifest.name} v{manifest.version}")
           except Exception as e:
             result = errorResult(fmt"Failed to install NIP: {e.msg}")
        else:
          let packageName = commandArgs[0]
          var stream = "stable"
          var cell = ""
          var preview = false
  
          # Parse install-specific options
          var i = 1
          while i < commandArgs.len:
            case commandArgs[i]:
            of "--stream":
              if i + 1 < commandArgs.len:
                stream = commandArgs[i + 1]
                i += 1
            of "--cell":
              if i + 1 < commandArgs.len:
                cell = commandArgs[i + 1]
                i += 1
            of "--preview":
              preview = true
            i += 1
  
          if cell != "":
            result = cellInstallCommand(cell, packageName, stream)
          else:
            result = installCommand(packageName, stream, cell, preview)

    of "remove":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip remove <package>")
      else:
        let pkgName = commandArgs[0]
        let home = getHomeDir()
        let nipDir = home / ".local/share/nexus/nips" / pkgName
        
        if dirExists(nipDir):
           # NIP Removal
           try:
             let currentLink = nipDir / "Current"
             if fileExists(currentLink) or symlinkExists(currentLink):
                let installDir = expandSymlink(currentLink)
                let manifestPath = installDir / "manifest.kdl"
                if fileExists(manifestPath):
                   let manifest = parseManifest(readFile(manifestPath), NIP, FormatKDL)
                   let casRoot = home / ".local/share/nexus/cas"
                   let installer = newNipInstaller(casRoot)
                   installer.removeNip(manifest)
                   result = successResult(fmt"Removed NIP {pkgName}")
                else:
                   removeDir(nipDir)
                   result = successResult(fmt"Removed NIP {pkgName} (forced)")
             else:
                removeDir(nipDir)
                result = successResult(fmt"Removed NIP {pkgName} (forced)")
           except Exception as e:
             result = errorResult(fmt"Failed to remove NIP: {e.msg}")
        else:
          # System Package Removal
          var verbose = "--verbose" in commandArgs or "-v" in commandArgs
          let exitCode = graft.removeCommand(commandArgs[0], verbose)
          result = if exitCode == 0: successResult("Package removed") else: errorResult("Failed to remove package")

    of "update":
      result = updateCommand()

    of "upgrade":
      result = upgradeCommand()

    # Information and search commands
    of "search":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip search <query>")
      else:
        result = commands.searchCommand(commandArgs.join(" "))

    of "sources":
      # List available package sources (nix, pkgsrc, gentoo)
      let packageName = if commandArgs.len > 0: commandArgs[0] else: ""
      let exitCode = build.listSourcesCommand(packageName)
      result = if exitCode == 0: successResult("") else: errorResult("Failed to list sources")

    of "info", "show":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip info <package>")
      else:
        result = commands.infoCommand(commandArgs[0])

    of "list", "ls":
      # Use graft coordinator's list command (unified database)
      var source = ""
      var verbose = false

      # Parse list-specific options
      var i = 0
      while i < commandArgs.len:
        case commandArgs[i]:
        of "--verbose", "-v":
          verbose = true
        of "--source":
          if i + 1 < commandArgs.len:
            source = commandArgs[i + 1]
            i += 1
        else:
          if source == "" and not commandArgs[i].startsWith("--"):
            source = commandArgs[i]
        i += 1

      let exitCode = graft.listCommand(source, verbose)
      result = if exitCode == 0: successResult("") else: errorResult("Failed to list packages")

    of "track":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip track <package>")
      else:
        result = trackCommand(commandArgs)

    # NIP Specific Commands
    of "pack":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip pack <source_dir> [output_file]")
      else:
        let sourceDir = commandArgs[0]
        var outputFile = if commandArgs.len > 1: commandArgs[1] else: ""
        
        if outputFile == "":
          try:
            let kdlPath = sourceDir / "manifest.kdl"
            if fileExists(kdlPath):
              let m = parseManifest(readFile(kdlPath), NIP, FormatKDL)
              outputFile = m.name & ".nip"
            else:
              let jsonPath = sourceDir / "manifest.json"
              if fileExists(jsonPath):
                let m = parseManifest(readFile(jsonPath), NIP, FormatJSON)
                outputFile = m.name & ".nip"
              else:
                result = errorResult("No manifest found")
                outputResult(result)
                return 1
          except Exception as e:
             result = errorResult("Failed to parse manifest: " & e.msg)
             outputResult(result)
             return 1
             
        try:
          let kdlPath = sourceDir / "manifest.kdl"
          let manifest = if fileExists(kdlPath):
             parseManifest(readFile(kdlPath), NIP, FormatKDL)
          else:
             parseManifest(readFile(sourceDir / "manifest.json"), NIP, FormatJSON)
             
          createArchive(manifest, sourceDir, outputFile)
          result = successResult(fmt"Created archive: {outputFile}")
        except Exception as e:
          result = errorResult(fmt"Failed to create archive: {e.msg}")

    of "run":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip run <package> [args...]")
      else:
        let packageName = commandArgs[0]
        let runArgs = if commandArgs.len > 1: commandArgs[1..^1] else: @[]
        
        let home = getHomeDir()
        let currentLink = home / ".local/share/nexus/nips" / packageName / "Current"
        
        if not symlinkExists(currentLink) and not fileExists(currentLink):
           result = errorResult(fmt"Package not found: {packageName}")
        else:
           try:
             let installDir = expandSymlink(currentLink)
             let manifestPath = installDir / "manifest.kdl"
             if not fileExists(manifestPath):
                result = errorResult("Corrupt installation: manifest.kdl missing")
             else:
                let manifest = parseManifest(readFile(manifestPath), NIP, FormatKDL)
                let casRoot = home / ".local/share/nexus/cas"
                let launcher = newLauncher(manifest, installDir, casRoot)
                launcher.run(runArgs)
                return 0
           except Exception as e:
             result = errorResult(fmt"Failed to run package: {e.msg}")

    # New CAS-aware commands
    of "where":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip where <package>")
      else:
        result = enhanced_search.whereCommand(commandArgs[0])

    of "variants":
      # Show installed variants with switching support
      if commandArgs.len == 0:
        result = errorResult("Usage: nip variants <package>")
      else:
        let exitCode = variant_switch.variantsListCommand(commandArgs[0])
        result = if exitCode == 0: successResult("") else: errorResult("Failed to list variants")

    of "cid":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip cid <package> [features...]")
      else:
        result = enhanced_search.cidCommand(commandArgs)

    # Grafting commands with variant support
    of "graft":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip graft <package> [+domain=value...] [--profile=<profile>]")
      else:
        # Parse package name and variant flags
        let packageName = commandArgs[0]
        var variantFlags: seq[string] = @[]
        var profilePath = ""
        var verbose = false

        # Parse options
        var i = 1
        while i < commandArgs.len:
          if commandArgs[i].startsWith("+"):
            variantFlags.add(commandArgs[i])
          elif commandArgs[i] == "--profile" and i + 1 < commandArgs.len:
            profilePath = commandArgs[i + 1]
            i += 1
          elif commandArgs[i] == "--verbose" or commandArgs[i] == "-v":
            verbose = true
          i += 1

        # Initialize graft commands
        graft.initGraftCommands(verbose)

        # Execute graft with variant support
        let exitCode = graft.graftCommand(packageName, verbose)
        if exitCode == 0:
          result = successResult(fmt"Successfully grafted {packageName}")
        else:
          result = errorResult(fmt"Failed to graft {packageName}")

    # Build command - compile from source with variants
    of "build":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip build <package> [+domain=value...] [--source=nix|pkgsrc|gentoo] [--verbose]\nExample: nip build firefox +wayland+lto --source=nix")
      else:
        # Parse package name and variant flags
        let packageName = commandArgs[0]
        var variantFlags: seq[string] = @[]
        var source = "auto"
        var verbose = false

        # Parse options
        var i = 1
        while i < commandArgs.len:
          if commandArgs[i].startsWith("+"):
            variantFlags.add(commandArgs[i])
          elif commandArgs[i].startsWith("--source="):
            source = commandArgs[i].split('=')[1]
          elif commandArgs[i] == "--verbose" or commandArgs[i] == "-v":
            verbose = true
          i += 1

        # Initialize build commands
        build.initBuildCommands(verbose)

        # Execute build with variant support and source selection
        let exitCode = build.buildCommand(packageName, variantFlags, source, verbose)
        if exitCode == 0:
          result = successResult(fmt"Successfully built {packageName}")
        else:
          result = errorResult(fmt"Failed to build {packageName}")

    of "convert":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip convert <package>")
      else:
        # TODO: Implement convert command integration
        result = successResult(fmt"Converting {commandArgs[0]} to .npk format (placeholder)")

    # Variant management commands
    of "variant":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip variant <subcommand> [args...]\nSubcommands: list, info, id, diff, explain, delete, count")
      else:
        graft.initGraftCommands(globalOptions.verbose)

        let subcommand = commandArgs[0].toLower()
        let subArgs = commandArgs[1..^1]
        var exitCode = 0

        case subcommand:
        of "list":
          if subArgs.len == 0:
            result = errorResult("Usage: nip variant list <package> [--json]")
          else:
            let jsonOutput = "--json" in subArgs
            exitCode = graft.variantListCommand(subArgs[0], jsonOutput)
            result = if exitCode == 0: successResult("") else: errorResult("Failed to list variants")

        of "info":
          if subArgs.len == 0:
            result = errorResult("Usage: nip variant info <fingerprint> [--json]")
          else:
            let jsonOutput = "--json" in subArgs
            exitCode = graft.variantInfoCommand(subArgs[0], jsonOutput)
            result = if exitCode == 0: successResult("") else: errorResult("Variant not found")

        of "id":
          if subArgs.len < 2:
            result = errorResult("Usage: nip variant id <package> <version> [+domain=value...]")
          else:
            let packageName = subArgs[0]
            let version = subArgs[1]
            var domainFlags: seq[string] = @[]
            for i in 2..<subArgs.len:
              if subArgs[i].startsWith("+"):
                domainFlags.add(subArgs[i])
            exitCode = graft.variantIdCommand(packageName, version, domainFlags)
            result = if exitCode == 0: successResult("") else: errorResult("Failed to calculate variant ID")

        of "diff":
          if subArgs.len < 2:
            result = errorResult("Usage: nip variant diff <fingerprint1> <fingerprint2> [--json]")
          else:
            let jsonOutput = "--json" in subArgs
            exitCode = graft.variantDiffCommand(subArgs[0], subArgs[1], jsonOutput)
            result = if exitCode == 0: successResult("") else: errorResult("Failed to compare variants")

        of "explain":
          if subArgs.len == 0:
            result = errorResult("Usage: nip variant explain <domain>[.<flag>] [--json]")
          else:
            let jsonOutput = "--json" in subArgs
            exitCode = graft.variantExplainCommand(subArgs[0], jsonOutput)
            result = if exitCode == 0: successResult("") else: errorResult("Failed to explain domain/flag")

        of "delete":
          if subArgs.len == 0:
            result = errorResult("Usage: nip variant delete <fingerprint>")
          else:
            exitCode = graft.variantDeleteCommand(subArgs[0])
            result = if exitCode == 0: successResult("Variant deleted") else: errorResult("Failed to delete variant")

        of "count":
          if subArgs.len == 0:
            result = errorResult("Usage: nip variant count <package>")
          else:
            exitCode = graft.variantCountCommand(subArgs[0])
            result = if exitCode == 0: successResult("") else: errorResult("Failed to count variants")

        else:
          result = errorResult(fmt"Unknown variant subcommand: {subcommand}")

    # Variant switching commands
    of "switch":
      if commandArgs.len < 2:
        result = errorResult("Usage: nip switch <package> <variant>\nExample: nip switch firefox +wayland+lto")
      else:
        let packageName = commandArgs[0]
        let targetVariant = commandArgs[1]
        let exitCode = variant_switch.switchCommand(packageName, targetVariant)
        result = if exitCode == 0: successResult(fmt"Switched to {targetVariant}") else: errorResult("Switch failed")

    of "active":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip active <package>")
      else:
        let exitCode = variant_switch.activeCommand(commandArgs[0])
        result = if exitCode == 0: successResult("") else: errorResult("Failed to show active variant")

    of "rollback":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip rollback <package>")
      else:
        let exitCode = variant_switch.rollbackCommand(commandArgs[0])
        result = if exitCode == 0: successResult("Rolled back successfully") else: errorResult("Rollback failed")

    # Migration commands
    of "migrate-flags":
      if commandArgs.len == 0:
        printMigrationHelp()
        return 0
      else:
        var filePath = ""
        var createBackup = true
        var outputPath = ""

        # Parse migration-specific options (--dry-run is handled by globalOptions)
        var i = 0
        while i < commandArgs.len:
          case commandArgs[i]:
          of "--no-backup":
            createBackup = false
          of "--output":
            if i + 1 < commandArgs.len:
              outputPath = commandArgs[i + 1]
              i += 1
          else:
            if filePath == "":
              filePath = commandArgs[i]
          i += 1

        # Use globalOptions.dryRun instead of parsing it again
        let exitCode = graft.migrateFlagsCommand(filePath, globalOptions.dryRun, createBackup, outputPath)
        result = if exitCode == 0: successResult("Migration complete") else: errorResult("Migration failed")

    of "check-flags":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip check-flags <flags...>")
      else:
        let exitCode = graft.checkLegacyFlagsCommand(commandArgs)
        result = if exitCode == 0: successResult("") else: errorResult("Check failed")

    # NexusCell commands
    of "cell":
      if commandArgs.len == 0:
        showCellHelp()
        return 0

      let cellSubcommand = commandArgs[0].toLower()
      let cellArgs = commandArgs[1..^1]

      case cellSubcommand:
      of "create":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell create <name> [options]")
        else:
          var cellType = "user"
          var isolation = "standard"
          var description = ""
          var profile = ""
          var customizations: seq[string] = @[]

          # Parse cell create options (Task 9.1)
          var i = 1
          while i < cellArgs.len:
            case cellArgs[i]:
            of "--type":
              if i + 1 < cellArgs.len:
                cellType = cellArgs[i + 1]
                i += 1
            of "--isolation":
              if i + 1 < cellArgs.len:
                isolation = cellArgs[i + 1]
                i += 1
            of "--description":
              if i + 1 < cellArgs.len:
                description = cellArgs[i + 1]
                i += 1
            of "--profile":
              if i + 1 < cellArgs.len:
                profile = cellArgs[i + 1]
                i += 1
            of "--customize":
              if i + 1 < cellArgs.len:
                customizations.add(cellArgs[i + 1])
                i += 1
            i += 1

          result = cellCreateCommand(cellArgs[0], cellType, isolation, description, profile, customizations)

      of "activate":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell activate <name>")
        else:
          result = cellActivateCommand(cellArgs[0])

      of "list":
        let verbose = "--verbose" in cellArgs or "-v" in cellArgs
        result = cellListCommand(verbose)

      of "delete":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell delete <name>")
        else:
          let force = "--force" in cellArgs
          result = cellDeleteCommand(cellArgs[0], force)

      of "info":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell info <name>")
        else:
          result = cellInfoCommand(cellArgs[0])

      of "status":
        result = cellStatusCommand()

      of "compare":
        result = cellComparisonCommand()

      of "clean":
        if cellArgs.len == 0:
          let aggressive = "--aggressive" in cellArgs
          result = cellCleanCommand("", aggressive)
        else:
          let aggressive = "--aggressive" in cellArgs
          result = cellCleanCommand(cellArgs[0], aggressive)

      of "export":
        if cellArgs.len < 2:
          result = errorResult("Usage: nip cell export <name> <path> [--include-data]")
        else:
          let includeData = "--include-data" in cellArgs
          result = cellExportCommand(cellArgs[0], cellArgs[1], includeData)

      of "import":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell import <path> [name]")
        else:
          let newName = if cellArgs.len > 1: cellArgs[1] else: ""
          result = cellImportCommand(cellArgs[0], newName)

      of "validate":
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell validate <name>")
        else:
          result = cellValidateCommand(cellArgs[0])

      of "profile":
        # Handle profile subcommands (Task 9.2)
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell profile <list|show|set> [args...]")
        else:
          let profileSubcmd = cellArgs[0].toLower()
          let profileArgs = cellArgs[1..^1]

          case profileSubcmd:
          of "list":
            result = cellProfileListCommand()

          of "show":
            if profileArgs.len == 0:
              result = errorResult("Usage: nip cell profile show <name>")
            else:
              result = cellProfileShowCommand(profileArgs[0])

          of "set":
            if profileArgs.len < 2:
              result = errorResult("Usage: nip cell profile set <name> <profile>")
            else:
              result = cellProfileSetCommand(profileArgs[0], profileArgs[1])

          else:
            result = errorResult(fmt"Unknown profile subcommand: {profileSubcmd}")

      of "verify":
        # Handle verify command (Task 9.3)
        if cellArgs.len == 0:
          result = errorResult("Usage: nip cell verify <name>")
        else:
          result = cellVerifyCommand(cellArgs[0])

      of "query":
        # Handle query command (Task 9.4)
        if cellArgs.len == 0:
          # Interactive mode
          result = cellQueryInteractiveCommand()
        else:
          let utcpAddress = cellArgs[0]
          let meth = if cellArgs.len > 1: cellArgs[1] else: "GET"
          result = cellQueryCommand(utcpAddress, meth)

      else:
        result = errorResult(fmt"Unknown cell command: {cellSubcommand}")

    # Reproducibility commands
    of "lock":
      result = lockCommand()

    of "restore":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip restore <lockfile>")
      else:
        result = restoreCommand(commandArgs[0])

    of "diff":
      result = diffCommand()

    # Verification commands
    of "verify":
      result = enhanced_search.verifyCommand(commandArgs)

    of "diagnose":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip diagnose <cid>")
      else:
        result = enhanced_search.diagnoseCommand(commandArgs)

    # Doctor/health check commands
    of "doctor":
      result = nipDoctorCommand(commandArgs)

    # Configuration commands
    of "config":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip config <show|init|path>")
      else:
        case commandArgs[0].toLower():
        of "show":
          result = showConfigCommand()
        of "init":
          result = initConfigCommand()
        of "path":
          result = showConfigPathCommand()
        else:
          result = errorResult(fmt"Unknown config subcommand: {commandArgs[0]}")

    # Dependency resolution commands
    of "resolve":
      let exitCode = resolve_command.resolveCommand(commandArgs)
      result = if exitCode == 0: successResult("") else: errorResult("Resolution failed")
    
    of "explain":
      let exitCode = resolve_command.explainCommand(commandArgs)
      result = if exitCode == 0: successResult("") else: errorResult("Explanation failed")
    
    of "conflicts":
      let exitCode = resolve_command.conflictsCommand(commandArgs)
      result = if exitCode == 0: successResult("") else: errorResult("Conflict check failed")
    
    # Dependency graph visualization
    of "deps", "dependencies":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip deps <package> [options]")
      else:
        var format = "tree"
        var showSizes = false

        # Parse deps options
        var i = 1
        while i < commandArgs.len:
          case commandArgs[i]:
          of "--format":
            if i + 1 < commandArgs.len:
              format = commandArgs[i + 1]
              i += 1
          of "--sizes":
            showSizes = true
          i += 1

        result = showDependencyGraph(commandArgs[0], format, showSizes)

    # Interactive shell
    of "shell":
      startInteractiveShell()
      return 0

    # Remote Repository Commands
    of "publish":
       if commandArgs.len == 0:
         result = errorResult("Usage: nip publish <source_dir> [name] [version] [repo_url]")
       else:
         let src = commandArgs[0]
         let name = if commandArgs.len > 1: commandArgs[1] else: ""
         let ver = if commandArgs.len > 2: commandArgs[2] else: ""
         let url = if commandArgs.len > 3: commandArgs[3] else: ""
         let res = waitFor nipPublish(src, name, ver, url, "")
         result = if res.success: successResult(res.message, res.data)
                  else: errorResult(res.message)
    
    of "fetch":
       if commandArgs.len == 0:
         result = errorResult("Usage: nip fetch <package> [repo] [version]")
       else:
         let pkg = commandArgs[0]
         let repo = if commandArgs.len > 1: commandArgs[1] else: ""
         let ver = if commandArgs.len > 2: commandArgs[2] else: ""
         let res = waitFor nipFetch(pkg, repo, ver)
         result = if res.success: successResult(res.message, res.data)
                  else: errorResult(res.message)

    of "repo":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip repo <add|list|sync|remove>")
      else:
        case commandArgs[0].toLower():
        of "list":
          let format = $globalContext.options.outputFormat
          let res = nipRepoList(format.toLower())
          result = if res.success: successResult(res.message, res.data)
                   else: errorResult(res.message)
        of "sync":
          let repoId = if commandArgs.len > 1: commandArgs[1] else: "all"
          let res = waitFor nipRepoSync(repoId)
          result = if res.success: successResult(res.message, res.data)
                   else: errorResult(res.message)
        of "add":
           if commandArgs.len < 2:
             result = errorResult("Usage: nip repo add <url> [name] [priority]")
           else:
             let url = commandArgs[1]
             let name = if commandArgs.len > 2: commandArgs[2] else: ""
             let priority = if commandArgs.len > 3: parseInt(commandArgs[3]) else: 50
             let res = waitFor nipRepoAdd(url, name, priority)
             result = if res.success: successResult(res.message, res.data)
                      else: errorResult(res.message)
        of "remove":
           if commandArgs.len < 2:
             result = errorResult("Usage: nip repo remove <id>")
           else:
             let id = commandArgs[1]
             let res = nipRepoRemove(id)
             result = if res.success: successResult(res.message, res.data)
                      else: errorResult(res.message)
        else:
           result = errorResult("Unknown repo subcommand")

    # Cache management commands
    of "cache":
      if commandArgs.len == 0:
        result = errorResult("Usage: nip cache <stats|clean|clear>")
      else:
        case commandArgs[0].toLower():
        of "stats":
          let exitCode = build.cacheStatsCommand()
          result = if exitCode == 0: successResult("") else: errorResult("Failed to show cache stats")
        of "clean":
          let exitCode = build.cacheCleanCommand()
          result = if exitCode == 0: successResult("Cache cleaned") else: errorResult("Failed to clean cache")
        of "clear":
          let exitCode = build.cacheClearCommand()
          result = if exitCode == 0: successResult("Cache cleared") else: errorResult("Failed to clear cache")
        else:
          result = errorResult(fmt"Unknown cache subcommand: {commandArgs[0]}")

    # Bootstrap management commands
    of "bootstrap":
      if commandArgs.len == 0:
        bootstrap_commands.bootstrapHelpCommand()
        return 0
      else:
        case commandArgs[0].toLower():
        of "list":
          let exitCode = bootstrap_commands.bootstrapListCommand()
          result = if exitCode == 0: successResult("") else: errorResult("Failed to list tools")
        of "install":
          if commandArgs.len < 2:
            result = errorResult("Usage: nip bootstrap install <tool>")
          else:
            let exitCode = bootstrap_commands.bootstrapInstallCommand(commandArgs[1])
            result = if exitCode == 0: successResult("Tool installed") else: errorResult("Failed to install tool")
        of "remove":
          if commandArgs.len < 2:
            result = errorResult("Usage: nip bootstrap remove <tool>")
          else:
            let exitCode = bootstrap_commands.bootstrapRemoveCommand(commandArgs[1])
            result = if exitCode == 0: successResult("Tool removed") else: errorResult("Failed to remove tool")
        of "info":
          if commandArgs.len < 2:
            result = errorResult("Usage: nip bootstrap info <tool>")
          else:
            let exitCode = bootstrap_commands.bootstrapInfoCommand(commandArgs[1])
            result = if exitCode == 0: successResult("") else: errorResult("Failed to show info")
        of "recipes":
          let exitCode = bootstrap_commands.bootstrapListRecipesCommand()
          result = if exitCode == 0: successResult("") else: errorResult("Failed to list recipes")
        of "update-recipes":
          let exitCode = bootstrap_commands.bootstrapUpdateRecipesCommand()
          result = if exitCode == 0: successResult("Recipes updated") else: errorResult("Failed to update recipes")
        of "validate":
          if commandArgs.len < 2:
            result = errorResult("Usage: nip bootstrap validate <tool>")
          else:
            let exitCode = bootstrap_commands.bootstrapValidateRecipeCommand(commandArgs[1])
            result = if exitCode == 0: successResult("Recipe is valid") else: errorResult("Recipe validation failed")
        of "help":
          bootstrap_commands.bootstrapHelpCommand()
          return 0
        else:
          result = errorResult(fmt"Unknown bootstrap subcommand: {commandArgs[0]}")

    # ==========================================================================
    # Format-Specific Commands (Task 39)
    # ==========================================================================
    
    # NPK (Binary Package) Commands
    of "npk":
      if commandArgs.len == 0:
        echo """
📦 NPK (NexusOS Package Kit) Commands

Usage: nip npk <subcommand> [options]

Subcommands:
  install <file.npk>  Install a binary package
  remove <package>    Remove an installed NPK package
  list                List installed NPK packages
  info <package>      Show NPK package information
  verify <file.npk>   Verify package integrity

Examples:
  nip npk install nginx-1.24.0.npk
  nip npk list
  nip npk info nginx"""
        return 0
      
      case commandArgs[0].toLower():
      of "install":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip npk install <file.npk>")
        else:
          echo fmt"📦 Installing NPK package: {commandArgs[1]}..."
          # TODO: Implement NPK installation via cas/packages
          result = successResult(fmt"NPK package would be installed: {commandArgs[1]} (placeholder)")
      of "remove":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip npk remove <package>")
        else:
          echo fmt"🗑 Removing NPK package: {commandArgs[1]}..."
          result = successResult(fmt"NPK package would be removed: {commandArgs[1]} (placeholder)")
      of "list":
        echo "📦 Installed NPK Packages:"
        echo "  (NPK package listing - placeholder)"
        result = successResult("")
      of "info":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip npk info <package>")
        else:
          echo fmt"📦 NPK Package: {commandArgs[1]}"
          echo "  (Package info - placeholder)"
          result = successResult("")
      of "verify":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip npk verify <file.npk>")
        else:
          echo fmt"🔍 Verifying NPK package: {commandArgs[1]}..."
          result = successResult(fmt"NPK package verified (placeholder)")
      else:
        result = errorResult(fmt"Unknown npk subcommand: {commandArgs[0]}")

    # App (NIP Application) Commands
    of "app":
      if commandArgs.len == 0:
        echo """
📱 App (NIP Application) Commands

Usage: nip app <subcommand> [options]

Subcommands:
  install <file.nip>  Install a NIP application
  run <app>           Run an installed application
  remove <app>        Remove an installed application
  list                List installed applications
  info <app>          Show application information
  update <app>        Update an application

Examples:
  nip app install firefox.nip
  nip app run firefox
  nip app list"""
        return 0
      
      case commandArgs[0].toLower():
      of "install":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip app install <file.nip>")
        else:
          echo fmt"📱 Installing application: {commandArgs[1]}..."
          # Re-use existing NIP install logic
          let target = commandArgs[1]
          if target.endsWith(".nip"):
            result = successResult(fmt"Please use 'nip install {target}' for NIP files")
          else:
            result = errorResult("App installation requires a .nip file")
      of "run":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip app run <app> [args...]")
        else:
          let appName = commandArgs[1]
          let appArgs = if commandArgs.len > 2: commandArgs[2..^1] else: @[]
          echo fmt"🚀 Running application: {appName}..."
          # TODO: Integrate with namespace launcher
          result = successResult(fmt"Application {appName} would run (placeholder)")
      of "remove":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip app remove <app>")
        else:
          echo fmt"🗑 Removing application: {commandArgs[1]}..."
          result = successResult(fmt"Use 'nip remove {commandArgs[1]}' for removal")
      of "list":
        echo "📱 Installed Applications:"
        let home = getHomeDir()
        let nipsDir = home / ".local/share/nexus/nips"
        if dirExists(nipsDir):
          for entry in walkDir(nipsDir):
            if entry.kind == pcDir:
              echo fmt"  • {entry.path.extractFilename}"
        else:
          echo "  (No applications installed)"
        result = successResult("")
      of "info":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip app info <app>")
        else:
          echo fmt"📱 Application: {commandArgs[1]}"
          let home = getHomeDir()
          let nipDir = home / ".local/share/nexus/nips" / commandArgs[1]
          if dirExists(nipDir):
            echo fmt"  Location: {nipDir}"
            if fileExists(nipDir / "manifest.kdl"):
              echo "  Manifest: present"
          else:
            echo "  (Not installed)"
          result = successResult("")
      of "update":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip app update <app>")
        else:
          echo fmt"📦 Updating application: {commandArgs[1]}..."
          result = successResult(fmt"Application update - placeholder")
      else:
        result = errorResult(fmt"Unknown app subcommand: {commandArgs[0]}")

    # NEXTER (Container) Commands
    of "nexter", "container":
      if commandArgs.len == 0:
        echo """
🐳 NEXTER (Container) Commands

Usage: nip nexter <subcommand> [options]

Subcommands:
  create <name>       Create a new container
  start <name>        Start a container
  stop <name>         Stop a running container
  remove <name>       Remove a container
  list                List all containers
  exec <name> <cmd>   Execute command in container
  status <name>       Show container status

Options:
  --type=<type>       Container type (system|user|ephemeral)
  --isolation=<mode>  Isolation mode (standard|strict|permissive)

Examples:
  nip nexter create dev-env --type=user
  nip nexter start dev-env
  nip nexter exec dev-env bash"""
        return 0
      
      case commandArgs[0].toLower():
      of "create":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip nexter create <name> [options]")
        else:
          let containerName = commandArgs[1]
          echo fmt"🐳 Creating container: {containerName}..."
          # TODO: Integrate with container manager
          result = successResult(fmt"Container '{containerName}' would be created (placeholder)")
      of "start":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip nexter start <name>")
        else:
          echo fmt"▶ Starting container: {commandArgs[1]}..."
          result = successResult(fmt"Container '{commandArgs[1]}' would start (placeholder)")
      of "stop":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip nexter stop <name>")
        else:
          echo fmt"⏹ Stopping container: {commandArgs[1]}..."
          result = successResult(fmt"Container '{commandArgs[1]}' would stop (placeholder)")
      of "remove":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip nexter remove <name>")
        else:
          echo fmt"🗑 Removing container: {commandArgs[1]}..."
          result = successResult(fmt"Container '{commandArgs[1]}' would be removed (placeholder)")
      of "list":
        echo "🐳 Containers:"
        echo "  (Container listing - placeholder)"
        result = successResult("")
      of "exec":
        if commandArgs.len < 3:
          result = errorResult("Usage: nip nexter exec <name> <command>")
        else:
          let containerName = commandArgs[1]
          let cmd = commandArgs[2..^1].join(" ")
          echo fmt"🔧 Executing in {containerName}: {cmd}"
          result = successResult("Command execution - placeholder")
      of "status":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip nexter status <name>")
        else:
          echo fmt"📊 Container Status: {commandArgs[1]}"
          echo "  State: unknown (placeholder)"
          result = successResult("")
      else:
        result = errorResult(fmt"Unknown nexter subcommand: {commandArgs[0]}")

    # Garbage Collection Commands
    of "gc":
      if commandArgs.len == 0:
        echo """
🧹 Garbage Collection Commands

Usage: nip gc [subcommand] [options]

Subcommands:
  run                 Run garbage collection
  status              Show GC status and statistics
  verify              Verify CAS integrity

Options:
  --dry-run           Show what would be collected without removing
  --force             Force collection even if recently run
  --threshold=<pct>   Size threshold percentage (default: 80)

Examples:
  nip gc run
  nip gc run --dry-run
  nip gc status"""
        return 0
      
      case commandArgs[0].toLower():
      of "run":
        echo "🧹 Running garbage collection..."
        let dryRun = "--dry-run" in commandArgs
        let force = "--force" in commandArgs
        
        if dryRun:
          echo "  [DRY RUN] Would analyze CAS for unreferenced objects..."
          echo "  [DRY RUN] Would remove 0 objects (placeholder)"
          result = successResult("Dry run complete")
        else:
          echo "  Analyzing CAS for unreferenced objects..."
          # TODO: Integrate with CAS garbage collection
          echo "  Collected 0 objects, freed 0 bytes (placeholder)"
          result = successResult("Garbage collection complete")
      of "status":
        echo "📊 Garbage Collection Status:"
        echo "  Last run: never (placeholder)"
        echo "  CAS objects: 0"
        echo "  Unreferenced: 0"
        echo "  Total size: 0 bytes"
        result = successResult("")
      of "verify":
        echo "🔍 Verifying CAS integrity..."
        echo "  Checking reference counts..."
        echo "  Verifying object hashes..."
        echo "  ✓ CAS integrity verified (placeholder)"
        result = successResult("Verification complete")
      else:
        result = errorResult(fmt"Unknown gc subcommand: {commandArgs[0]}")

    # CAS (Content-Addressable Storage) Commands
    of "cas":
      if commandArgs.len == 0:
        echo """
💾 CAS (Content-Addressable Storage) Commands

Usage: nip cas <subcommand> [options]

Subcommands:
  stats               Show CAS statistics
  verify              Verify CAS integrity
  list                List objects in CAS
  info <hash>         Show object information

Examples:
  nip cas stats
  nip cas verify
  nip cas info xxh3-abc123..."""
        return 0
      
      case commandArgs[0].toLower():
      of "stats":
        echo "💾 CAS Statistics:"
        # TODO: Integrate with CAS manager
        echo "  Root: ~/.local/share/nexus/cas"
        echo "  Objects: 0"
        echo "  Total size: 0 bytes"
        echo "  Compression: enabled"
        result = successResult("")
      of "verify":
        echo "🔍 Verifying CAS..."
        result = successResult("CAS verification - placeholder")
      of "list":
        echo "💾 CAS Objects:"
        echo "  (Object listing - placeholder)"
        result = successResult("")
      of "info":
        if commandArgs.len < 2:
          result = errorResult("Usage: nip cas info <hash>")
        else:
          echo fmt"💾 Object: {commandArgs[1]}"
          echo "  (Object info - placeholder)"
          result = successResult("")
      else:
        result = errorResult(fmt"Unknown cas subcommand: {commandArgs[0]}")

    # Help and version
    of "help":
      if commandArgs.len > 0:
        showCommandHelp(commandArgs[0])
      else:
        showMainHelp()
      return 0

    of "version":
      echo NimPakBanner
      return 0

    else:
      result = errorResult(fmt"Unknown command: {command}. Use 'nip help' for available commands.")

    # Output the result
    outputResult(result)
    return result.exitCode

  except Exception as e:
    let errorResult = errorResult(fmt"Unexpected error: {e.msg}")
    outputResult(errorResult)
    return 1

# =============================================================================
# Main Entry Point
# =============================================================================

when isMainModule:
  let args = commandLineParams()
  let exitCode = dispatchCommand(args)
  quit(exitCode)
