import std/[unittest, os, tempfiles, options, strutils]
import nip/nip_installer
import nip/manifest_parser
import nip/cas

suite "NIP Advanced Desktop Integration Tests":
  
  setup:
    let tempDir = createTempDir("nip_test_desktop_", "")
    let casRoot = tempDir / "cas"
    let mockHome = tempDir / "home"
    
    createDir(mockHome / ".local/share/nexus/nips")
    createDir(mockHome / ".local/share/applications")
    createDir(mockHome / ".local/share/icons/hicolor/48x48/apps")
    createDir(casRoot)
    
    discard initCasManager(casRoot, casRoot)
    
    var ni = NipInstaller(
      casRoot: casRoot,
      installRoot: mockHome / ".local/share/nexus/nips",
      appsRoot: mockHome / ".local/share/applications",
      iconsRoot: mockHome / ".local/share/icons",
      dryRun: false # We want to test file creation
    )

  teardown:
    removeDir(tempDir)

  test "Install NIP with Icon and StartupWMClass":
    # 1. Prepare CAS (Icon file)
    let iconContent = "fake png content"
    let casObj = storeObject(iconContent, ni.casRoot)
    
    # 2. Create Manifest
    var manifest = PackageManifest(
      name: "icon-app",
      version: parseSemanticVersion("1.0.0"),
      license: "MIT",
      artifactHash: "hash123"
    )
    
    manifest.files.add(FileSpec(
      path: "icon.png",
      hash: string(casObj.hash),
      size: iconContent.len,
      permissions: "644"
    ))
    
    manifest.desktop = some(DesktopIntegration(
      displayName: "Icon App",
      icon: some("icon.png"),
      startupWMClass: some("IconAppWindow")
    ))
    
    # 3. Install
    # Note: update-desktop-database will fail in test env if not in PATH or no permissions
    # But execCmd returns exit code, we discard it in code.
    # Ideally we should mock execCmd, but for integration test we just check files.
    ni.installNip(manifest)
    
    # 4. Verify Icon Installation
    let iconDest = ni.iconsRoot / "hicolor/48x48/apps/icon-app.png"
    check fileExists(iconDest)
    check readFile(iconDest) == iconContent
    
    # 5. Verify StartupWMClass in .desktop
    let desktopFile = ni.appsRoot / "icon-app.desktop"
    check fileExists(desktopFile)
    let content = readFile(desktopFile)
    check content.contains("StartupWMClass=IconAppWindow")
    
    # 6. Remove
    ni.removeNip(manifest)
    
    # 7. Verify Removal
    check not fileExists(iconDest)
    check not fileExists(desktopFile)

  test "Install NIP with System Icon (No File Copy)":
    var manifest = PackageManifest(
      name: "sys-icon-app",
      version: parseSemanticVersion("1.0.0"),
      license: "MIT",
      artifactHash: "hash456"
    )
    
    manifest.desktop = some(DesktopIntegration(
      displayName: "Sys Icon App",
      icon: some("firefox") # System icon name
    ))
    
    ni.installNip(manifest)
    
    # Verify NO icon file copied (since "firefox" doesn't end in .png/.svg)
    let iconDest = ni.iconsRoot / "hicolor/48x48/apps/sys-icon-app.png"
    check not fileExists(iconDest)
    
    # Verify .desktop has Icon=firefox
    let desktopFile = ni.appsRoot / "sys-icon-app.desktop"
    check readFile(desktopFile).contains("Icon=firefox")
