## test_updates.nim
## Tests for automatic update system

import std/[unittest, os, times, json, options, strutils]
import ../src/nimpak/update/[update_checker, update_manager]

suite "Update Configuration":
  test "Load default config":
    let config = loadConfig("/tmp/nonexistent-update-config.json")
    check:
      config.enabled == true
      config.channel == Stable
      config.frequency == Weekly
      config.notifyRecipes == true
      config.notifyTools == true
      config.notifyNip == true

  test "Save and load config":
    let tempConfig = getTempDir() / "test-update-config.json"

    var config = UpdateConfig()
    config.enabled = false
    config.channel = Beta
    config.frequency = Daily
    config.lastCheck = getTime()
    config.notifyRecipes = false
    config.notifyTools = true
    config.notifyNip = false

    saveConfig(config, tempConfig)

    let loaded = loadConfig(tempConfig)
    check:
      loaded.enabled == false
      loaded.channel == Beta
      loaded.frequency == Daily
      loaded.notifyRecipes == false
      loaded.notifyTools == true
      loaded.notifyNip == false

    removeFile(tempConfig)

  test "Config with partial fields":
    let tempConfig = getTempDir() / "test-partial-update-config.json"
    writeFile(tempConfig, """{"enabled": false, "channel": "nightly"}""")

    let config = loadConfig(tempConfig)
    check:
      config.enabled == false
      config.channel == Nightly
      config.frequency == Weekly  # default

    removeFile(tempConfig)

suite "Update Checker":
  setup:
    var config = UpdateConfig()
    config.enabled = true
    config.channel = Stable
    config.frequency = Weekly
    config.lastCheck = fromUnix(0)

    let checker = newUpdateChecker(config)

  test "Create checker":
    check:
      checker != nil
      checker.config.enabled == true
      checker.config.channel == Stable

  test "Should check - never checked":
    check:
      checker.shouldCheck() == true

  test "Should check - daily frequency":
    checker.config.frequency = Daily
    checker.config.lastCheck = getTime() - initDuration(hours = 25)
    check:
      checker.shouldCheck() == true

  test "Should not check - too soon":
    checker.config.frequency = Daily
    checker.config.lastCheck = getTime() - initDuration(hours = 12)
    check:
      checker.shouldCheck() == false

  test "Should not check - disabled":
    checker.config.enabled = false
    check:
      checker.shouldCheck() == false

  test "Should not check - never frequency":
    checker.config.frequency = Never
    check:
      checker.shouldCheck() == false

suite "Update Manager":
  setup:
    let tempDir = getTempDir() / "test-update-manager"
    removeDir(tempDir)
    createDir(tempDir)

    let manager = newUpdateManager(verbose = false)

  teardown:
    removeDir(tempDir)

  test "Create manager":
    check:
      manager != nil
      dirExists(manager.backupDir)

  test "Create backup - directory":
    let testDir = tempDir / "test-component"
    createDir(testDir)
    writeFile(testDir / "file.txt", "test content")

    let backupPath = manager.createBackup("test", testDir)

    check:
      backupPath.len > 0
      dirExists(backupPath)
      fileExists(backupPath / "file.txt")

  test "Create backup - file":
    let testFile = tempDir / "test-file.txt"
    writeFile(testFile, "test content")

    let backupPath = manager.createBackup("test", testFile)

    check:
      backupPath.len > 0
      fileExists(backupPath)

  test "Restore backup - directory":
    let testDir = tempDir / "test-component"
    createDir(testDir)
    writeFile(testDir / "file.txt", "original")

    let backupPath = manager.createBackup("test", testDir)

    # Modify original
    writeFile(testDir / "file.txt", "modified")

    # Restore
    let restored = manager.restoreBackup(backupPath, testDir)

    check:
      restored == true
      readFile(testDir / "file.txt") == "original"

  test "List backups":
    # Create some test backups
    let testFile1 = tempDir / "test1.txt"
    writeFile(testFile1, "test1")
    discard manager.createBackup("component1", testFile1)

    let testFile2 = tempDir / "test2.txt"
    writeFile(testFile2, "test2")
    discard manager.createBackup("component2", testFile2)

    let backups = manager.listBackups()

    check:
      backups.len >= 2

  test "Clean old backups":
    # Create old backup
    let testFile = tempDir / "old-test.txt"
    writeFile(testFile, "old")
    let backupPath = manager.createBackup("old-component", testFile)

    # Manually set old timestamp
    setLastModificationTime(backupPath, getTime() - initDuration(days = 31))

    # Clean backups older than 30 days
    let removed = manager.cleanOldBackups(keepDays = 30)

    check:
      removed >= 1

suite "Update Frequency":
  test "Daily frequency":
    check:
      $Daily == "daily"

  test "Weekly frequency":
    check:
      $Weekly == "weekly"

  test "Monthly frequency":
    check:
      $Monthly == "monthly"

  test "Never frequency":
    check:
      $Never == "never"

suite "Update Channel":
  test "Stable channel":
    check:
      $Stable == "stable"

  test "Beta channel":
    check:
      $Beta == "beta"

  test "Nightly channel":
    check:
      $Nightly == "nightly"

suite "Update Info":
  test "Format update notification":
    var info = UpdateInfo()
    info.component = "recipes"
    info.currentVersion = "abc123"
    info.latestVersion = "def456"
    info.updateAvailable = true
    info.changelog = "- Added new recipes\n- Fixed bugs"

    let notification = formatUpdateNotification(info)

    check:
      notification.contains("recipes")
      notification.contains("abc123")
      notification.contains("def456")
      notification.toLower().contains("changelog")

echo "✅ All update tests completed"
