## system_integration.nim
## System integration for NIP - PATH, libraries, shell integration

import std/[os, strformat, strutils, osproc]

type
  ShellType* = enum
    Bash, Zsh, Sh, Fish, Unknown

proc detectShell*(): ShellType =
  ## Detect the current shell
  let shell = getEnv("SHELL")
  if "bash" in shell:
    return Bash
  elif "zsh" in shell:
    return Zsh
  elif "fish" in shell:
    return Fish
  elif shell.endsWith("/sh"):
    return Sh
  else:
    return Unknown

proc createPathSetupScript*(linksDir: string = "/System/Links"): string =
  ## Generate shell script to add NIP to PATH
  result = fmt"""#!/bin/sh
# NIP System Integration
# Add NIP-managed executables to PATH

# Add NIP executables to PATH
if [ -d "{linksDir}/Executables" ]; then
    export PATH="{linksDir}/Executables:$PATH"
fi

# Add NIP libraries to library path
if [ -d "{linksDir}/Libraries" ]; then
    export LD_LIBRARY_PATH="{linksDir}/Libraries:$LD_LIBRARY_PATH"
fi

# Add NIP pkg-config path
if [ -d "{linksDir}/Libraries/pkgconfig" ]; then
    export PKG_CONFIG_PATH="{linksDir}/Libraries/pkgconfig:$PKG_CONFIG_PATH"
fi
"""

proc installPathSetup*(linksDir: string = "/System/Links"): bool =
  ## Install PATH setup script to /etc/profile.d/
  let script = createPathSetupScript(linksDir)
  let scriptPath = "/etc/profile.d/nip.sh"

  try:
    # Check if we have write permission
    if not dirExists("/etc/profile.d"):
      echo "⚠️  /etc/profile.d does not exist, skipping PATH setup"
      return false

    writeFile(scriptPath, script)

    # Make it executable
    setFilePermissions(scriptPath, {fpUserExec, fpUserRead, fpUserWrite,
                                     fpGroupRead, fpGroupExec,
                                     fpOthersRead, fpOthersExec})

    echo fmt"✅ Installed PATH setup script to {scriptPath}"
    echo "   Please restart your shell or run: source /etc/profile.d/nip.sh"
    return true

  except IOError, OSError:
    echo "⚠️  Could not install PATH setup (requires root)"
    echo "   You can manually add to your shell profile:"
    echo ""
    echo script
    return false

proc createLdConfig*(linksDir: string = "/System/Links"): string =
  ## Generate ld.so.conf.d configuration
  fmt"{linksDir}/Libraries"

proc installLdConfig*(linksDir: string = "/System/Links"): bool =
  ## Install library path configuration
  let config = createLdConfig(linksDir)
  let configPath = "/etc/ld.so.conf.d/nip.conf"

  try:
    if not dirExists("/etc/ld.so.conf.d"):
      echo "⚠️  /etc/ld.so.conf.d does not exist, skipping library config"
      return false

    writeFile(configPath, config & "\n")
    echo fmt"✅ Installed library config to {configPath}"

    # Run ldconfig to update cache
    let (output, exitCode) = execCmdEx("ldconfig")
    if exitCode == 0:
      echo "✅ Updated library cache with ldconfig"
    else:
      echo "⚠️  Could not run ldconfig (requires root)"

    return true

  except IOError, OSError:
    echo "⚠️  Could not install library config (requires root)"
    return false

proc setupSystemIntegration*(linksDir: string = "/System/Links"): bool =
  ## Setup complete system integration
  echo "🔧 Setting up NIP system integration..."
  echo ""

  var success = true

  # Install PATH setup
  if not installPathSetup(linksDir):
    success = false

  echo ""

  # Install library config
  if not installLdConfig(linksDir):
    success = false

  echo ""

  if success:
    echo "✅ System integration complete!"
  else:
    echo "⚠️  System integration partially complete (some steps require root)"

  return success

proc generateShellRc*(shell: ShellType, linksDir: string = "/System/Links"): string =
  ## Generate shell-specific RC configuration
  case shell
  of Bash, Sh:
    result = fmt"""
# NIP Package Manager Integration
if [ -f /etc/profile.d/nip.sh ]; then
    . /etc/profile.d/nip.sh
fi
"""
  of Zsh:
    result = fmt"""
# NIP Package Manager Integration
if [ -f /etc/profile.d/nip.sh ]; then
    source /etc/profile.d/nip.sh
fi
"""
  of Fish:
    result = fmt"""
# NIP Package Manager Integration
if test -d {linksDir}/Executables
    set -gx PATH {linksDir}/Executables $PATH
end
if test -d {linksDir}/Libraries
    set -gx LD_LIBRARY_PATH {linksDir}/Libraries $LD_LIBRARY_PATH
end
"""
  of Unknown:
    result = "# Unknown shell type"

proc showShellIntegrationHelp*() =
  ## Show help for manual shell integration
  let shell = detectShell()
  let shellName = case shell
    of Bash: "bash (~/.bashrc)"
    of Zsh: "zsh (~/.zshrc)"
    of Fish: "fish (~/.config/fish/config.fish)"
    of Sh: "sh (~/.profile)"
    of Unknown: "your shell"

  echo fmt"📝 To integrate NIP with {shellName}, add:"
  echo ""
  echo generateShellRc(shell)
