## Resolve Command - CLI Interface for Dependency Resolution
##
## This module provides the CLI interface for the dependency resolver,
## allowing users to resolve, explain, and inspect package dependencies.

import strformat
import tables
import terminal

# ============================================================================
# Type Definitions
# ============================================================================

import ../resolver/orchestrator
import ../resolver/variant_types
import ../resolver/dependency_graph
import ../resolver/conflict_detection
import std/[options, times]

type
  VersionConstraint* = object
    operator*: string
    version*: string

# ============================================================================
# Helper Functions
# ============================================================================

proc loadRepositories*(): seq[Repository] =
  ## Load repositories from configuration
  result = @[
    Repository(name: "main", url: "https://packages.nexusos.org/main", priority: 100),
    Repository(name: "community", url: "https://packages.nexusos.org/community", priority: 50)
  ]



proc parseVersionConstraint*(constraint: string): VersionConstraint =
  ## Parse version constraint string
  result = VersionConstraint(operator: "any", version: constraint)

proc formatError*(msg: string): string =
  ## Format error message
  result = fmt"Error: {msg}"



# ============================================================================
# Command: nip resolve
# ============================================================================

proc resolveCommand*(args: seq[string]): int =
  ## Handle 'nip resolve <package>' command
  
  if args.len < 1:
    echo "Usage: nip resolve <package> [constraint] [options]"
    echo ""
    echo "Options:"
    echo "  --use-flags=<flags>    Comma-separated USE flags"
    echo "  --libc=<libc>          C library (musl, glibc)"
    echo "  --allocator=<alloc>    Memory allocator (jemalloc, tcmalloc, default)"
    echo "  --json                 Output in JSON format"
    return 1
  
  let packageName = args[0]
  var jsonOutput = false
  
  # Parse arguments
  for arg in args[1..^1]:
    if arg == "--json":
      jsonOutput = true
  
  try:
    # Initialize Orchestrator
    let repos = loadRepositories()
    let config = defaultConfig()
    let orchestrator = newResolutionOrchestrator(repos, config)
    
    # Create demand (default for now)
    let demand = VariantDemand(
      packageName: packageName,
      variantProfile: VariantProfile(hash: "any")
    )
    
    # Resolve
    let result = orchestrator.resolve(packageName, "*", demand)
    
    if result.isOk:
      let res = result.value
      if jsonOutput:
        echo fmt"""{{
  "success": true,
  "package": "{packageName}",
  "packageCount": {res.packageCount},
  "resolutionTime": {res.resolutionTime},
  "cacheHit": {res.cacheHit},
  "installOrder": []
}}"""
      else:
        stdout.styledWrite(fgGreen, "✅ Resolution successful!\n")
        echo ""
        echo fmt"📦 Package: {packageName}"
        echo fmt"⏱️  Time: {res.resolutionTime * 1000:.2f}ms"
        echo fmt"📚 Packages: {res.packageCount}"
        echo fmt"💾 Cache Hit: {res.cacheHit}"
        echo ""
        
        echo "📋 Resolution Plan:"
        for term in res.installOrder:
          stdout.styledWrite(fgCyan, fmt"  • {term.packageName}")
          stdout.write(fmt" ({term.version})")
          stdout.styledWrite(fgYellow, fmt" [{term.source}]")
          echo ""
        echo ""
        
    else:
      let err = result.error
      if jsonOutput:
        echo fmt"""{{
  "success": false,
  "error": "{err.details}"
}}"""
      else:
        stdout.styledWrite(fgRed, "❌ Resolution Failed!\n")
        echo formatError(err)
    
    return if result.isOk: 0 else: 1
    
  except Exception as e:
    if jsonOutput:
      echo fmt"""{{
  "success": false,
  "error": "{e.msg}"
}}"""
    else:
      stdout.styledWrite(fgRed, "❌ Error!\n")
      echo fmt"Error: {e.msg}"
    return 1

# ============================================================================
# Command: nip explain
# ============================================================================

proc explainCommand*(args: seq[string]): int =
  ## Handle 'nip explain <package>' command
  
  if args.len < 1:
    echo "Usage: nip explain <package> [options]"
    return 1
  
  let packageName = args[0]
  var jsonOutput = false
  
  for arg in args[1..^1]:
    if arg == "--json":
      jsonOutput = true
  
  try:
    if jsonOutput:
      echo fmt"""{{
  "success": true,
  "package": "{packageName}",
  "version": "1.0.0",
  "variant": "default",
  "buildHash": "blake3-abc123",
  "source": "main",
  "dependencyCount": 0,
  "dependencies": []
}}"""
    else:
      stdout.styledWrite(fgCyan, fmt"📖 Explaining resolution for: {packageName}\n")
      echo ""
      echo "Resolution explanation:"
      echo fmt"  • Package source: main"
      echo fmt"  • Version selected: 1.0.0"
      echo fmt"  • Variant: default"
      echo fmt"  • Dependencies: 0 packages"
      echo ""
    
    return 0
    
  except Exception as e:
    if jsonOutput:
      echo fmt"""{{
  "success": false,
  "error": "{e.msg}"
}}"""
    else:
      stdout.styledWrite(fgRed, "❌ Error!\n")
      echo fmt"Error: {e.msg}"
    return 1

# ============================================================================
# Command: nip conflicts
# ============================================================================

proc conflictsCommand*(args: seq[string]): int =
  ## Handle 'nip conflicts' command
  
  var jsonOutput = false
  
  for arg in args:
    if arg == "--json":
      jsonOutput = true
  
  try:
    if jsonOutput:
      echo """{"success": true, "conflicts": []}"""
    else:
      stdout.styledWrite(fgGreen, "✅ No conflicts detected!\n")
      echo ""
      echo "All installed packages are compatible."
      echo ""
    
    return 0
    
  except Exception as e:
    if jsonOutput:
      echo fmt"""{{
  "success": false,
  "error": "{e.msg}"
}}"""
    else:
      stdout.styledWrite(fgRed, "❌ Error!\n")
      echo fmt"Error: {e.msg}"
    return 1

# ============================================================================
# Command: nip variants
# ============================================================================

proc variantsCommand*(args: seq[string]): int =
  ## Handle 'nip variants <package>' command
  
  if args.len < 1:
    echo "Usage: nip variants <package> [options]"
    return 1
  
  let packageName = args[0]
  var jsonOutput = false
  
  for arg in args[1..^1]:
    if arg == "--json":
      jsonOutput = true
  
  try:
    if jsonOutput:
      echo fmt"""{{
  "package": "{packageName}",
  "variants": {{
    "useFlags": [
      {{"flag": "ssl", "description": "Enable SSL/TLS support", "default": false}},
      {{"flag": "http2", "description": "Enable HTTP/2 support", "default": false}}
    ],
    "libc": [
      {{"option": "musl", "description": "Lightweight C library", "default": true}},
      {{"option": "glibc", "description": "GNU C library", "default": false}}
    ],
    "allocator": [
      {{"option": "jemalloc", "description": "High-performance allocator", "default": true}},
      {{"option": "tcmalloc", "description": "Google's thread-caching allocator", "default": false}}
    ]
  }}
}}"""
    else:
      stdout.styledWrite(fgCyan, fmt"🎨 Available variants for: {packageName}\n")
      echo ""
      echo "USE flags:"
      echo "  • ssl (default) - Enable SSL/TLS support"
      echo "  • http2 - Enable HTTP/2 support"
      echo ""
      echo "libc options:"
      echo "  • musl (default) - Lightweight C library"
      echo "  • glibc - GNU C library"
      echo ""
      echo "Allocator options:"
      echo "  • jemalloc (default) - High-performance allocator"
      echo "  • tcmalloc - Google's thread-caching allocator"
      echo ""
    
    return 0
    
  except Exception as e:
    if jsonOutput:
      echo fmt"""{{
  "success": false,
  "error": "{e.msg}"
}}"""
    else:
      stdout.styledWrite(fgRed, "❌ Error!\n")
      echo fmt"Error: {e.msg}"
    return 1

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

when isMainModule:
  import os
  
  let args = commandLineParams()
  
  if args.len == 0:
    echo "NIP Dependency Resolver"
    echo ""
    echo "Usage: nip <command> [args]"
    echo ""
    echo "Commands:"
    echo "  resolve <package>  - Resolve dependencies"
    echo "  explain <package>  - Explain resolution decisions"
    echo "  conflicts          - Show detected conflicts"
    echo "  variants <package> - Show available variants"
    echo ""
    quit(1)
  
  let command = args[0]
  let commandArgs = args[1..^1]
  
  let exitCode = case command:
    of "resolve": resolveCommand(commandArgs)
    of "explain": explainCommand(commandArgs)
    of "conflicts": conflictsCommand(commandArgs)
    of "variants": variantsCommand(commandArgs)
    else:
      echo fmt"Unknown command: {command}"
      1
  
  quit(exitCode)
