## Test suite for Nippels Profile Manager Integration (Task 8.1)
##
## Tests the integration of ProfileManager with NippelManager

import std/[unittest, os, times, options, json, strutils]
import ../src/nimpak/nippels
import ../src/nimpak/profile_manager
import ../src/nimpak/nippel_types
import ../src/nimpak/utils/resultutils

suite "Nippels Profile Manager Integration (Task 8.1)":
  var manager: NippelManager
  let testRoot = getTempDir() / "nippels_profile_test_" & $epochTime().int

  setup:
    # Create test directory
    createDir(testRoot)
    manager = newNippelManager(testRoot)

  teardown:
    # Clean up test directory
    if dirExists(testRoot):
      removeDir(testRoot)

  test "ProfileManager is initialized in NippelManager":
    check manager.profileManager.profilesDir.len > 0
    check manager.profileManager.customProfilesDir.len > 0

  test "Create Nippel with default Homestation profile":
    let result = manager.createNippel("test-homestation")
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == Homestation
      check nippel.isolationLevel == Standard
      check nippel.profileSettings.desktopIntegration == true
      check nippel.profileSettings.networkAccess == Relaxed
      check nippel.profileSettings.auditingEnabled == false

  test "Create Nippel with Workstation profile":
    let result = manager.createNippel("test-workstation", Workstation)
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == Workstation
      check nippel.isolationLevel == Standard
      check nippel.profileSettings.desktopIntegration == true
      check nippel.profileSettings.networkAccess == Full
      check nippel.profileSettings.resourceLimits.maxMemory == 8 * 1024 * 1024 * 1024

  test "Create Nippel with Server profile":
    let result = manager.createNippel("test-server", Server)
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == Server
      check nippel.isolationLevel == Strict
      check nippel.profileSettings.desktopIntegration == false
      check nippel.profileSettings.networkAccess == Full
      check nippel.profileSettings.auditingEnabled == true

  test "Create Nippel with Satellite profile":
    let result = manager.createNippel("test-satellite", Satellite)
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == Satellite
      check nippel.isolationLevel == Strict
      check nippel.profileSettings.desktopIntegration == true
      check nippel.profileSettings.networkAccess == Limited
      check nippel.profileSettings.auditingEnabled == true

  test "Create Nippel with NetworkIOT profile":
    let result = manager.createNippel("test-iot", NetworkIOT)
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == NetworkIOT
      check nippel.isolationLevel == Strict
      check nippel.profileSettings.desktopIntegration == false
      check nippel.profileSettings.networkAccess == Limited
      check nippel.profileSettings.resourceLimits.maxMemory == 512 * 1024 * 1024

  test "Create Nippel with profile overrides":
    let overrides = ProfileOverrides(
      isolationLevel: some(Strict),
      networkAccess: some(Limited),
      auditingEnabled: some(true)
    )

    let result = manager.createNippel("test-custom", Homestation, overrides)
    check result.isOk

    if result.isOk:
      let nippel = result.value
      check nippel.profile == Homestation
      check nippel.isolationLevel == Strict  # Overridden
      check nippel.profileSettings.networkAccess == Limited  # Overridden
      check nippel.profileSettings.auditingEnabled == true  # Overridden
      check nippel.profileSettings.desktopIntegration == true  # Not overridden

  test "Change Nippel profile after creation":
    # Create with Homestation profile
    let createResult = manager.createNippel("test-change", Homestation)
    check createResult.isOk

    # Change to Server profile
    let changeResult = manager.changeNippelProfile("test-change", Server)
    check changeResult.isOk

    # Verify the change
    let cellRoot = testRoot / "test-change"
    let configPath = cellRoot / "cell.json"
    check fileExists(configPath)

    # Read and verify configuration
    let config = parseJson(readFile(configPath))
    check config["profile"]["type"].getStr() == "Server"
    check config["profile"]["isolation"].getStr() == "Strict"
    check config["profile"]["desktopIntegration"].getBool() == false
    check config["profile"]["auditingEnabled"].getBool() == true

  test "Customize Nippel profile settings":
    # Create with default Homestation profile
    let createResult = manager.createNippel("test-customize", Homestation)
    check createResult.isOk

    # Customize settings
    let overrides = ProfileOverrides(
      isolationLevel: some(Strict),
      desktopIntegration: some(false),
      auditingEnabled: some(true)
    )

    let customizeResult = manager.customizeNippelProfile("test-customize", overrides)
    check customizeResult.isOk

    # Verify the customization
    let cellRoot = testRoot / "test-customize"
    let configPath = cellRoot / "cell.json"
    check fileExists(configPath)

    # Read and verify configuration
    let config = parseJson(readFile(configPath))
    check config["profile"]["type"].getStr() == "Homestation"  # Profile unchanged
    check config["profile"]["isolation"].getStr() == "Strict"  # Customized
    check config["profile"]["desktopIntegration"].getBool() == false  # Customized
    check config["profile"]["auditingEnabled"].getBool() == true  # Customized

  test "ProfileManager caches loaded profiles":
    # Load same profile multiple times
    let settings1 = manager.profileManager.loadProfile(Workstation)
    let settings2 = manager.profileManager.loadProfile(Workstation)

    # Should return same settings
    check settings1.isolationLevel == settings2.isolationLevel
    check settings1.desktopIntegration == settings2.desktopIntegration
    check settings1.networkAccess == settings2.networkAccess

  test "Error handling: Change profile for non-existent Nippel":
    let result = manager.changeNippelProfile("non-existent", Server)
    check result.isErr
    check "not found" in result.error.toLowerAscii()

  test "Error handling: Customize profile for non-existent Nippel":
    let overrides = ProfileOverrides(isolationLevel: some(Strict))
    let result = manager.customizeNippelProfile("non-existent", overrides)
    check result.isErr
    check "not found" in result.error.toLowerAscii()

  test "Error handling: Create duplicate Nippel":
    let result1 = manager.createNippel("test-duplicate")
    check result1.isOk

    let result2 = manager.createNippel("test-duplicate")
    check result2.isErr
    check "already exists" in result2.error.toLowerAscii()

echo "✅ All Task 8.1 tests completed"
