## test_remote_cache.nim
## Tests for remote binary cache

import std/[unittest, os, tables, times, options]
import ../src/nimpak/build/[binary_cache, remote_cache]

suite "Remote Cache Configuration":
  test "Load default config":
    let config = loadConfig("/tmp/nonexistent-config.json")
    check:
      config.timeout == DefaultTimeout
      config.enabled == false
      config.url == ""
      config.apiKey == ""

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

    var config = RemoteCacheConfig()
    config.url = "https://cache.example.com"
    config.apiKey = "test-key-123"
    config.timeout = 600
    config.enabled = true

    saveConfig(config, tempConfig)

    let loaded = loadConfig(tempConfig)
    check:
      loaded.url == "https://cache.example.com"
      loaded.apiKey == "test-key-123"
      loaded.timeout == 600
      loaded.enabled == true

    removeFile(tempConfig)

  test "Config with missing fields":
    let tempConfig = getTempDir() / "test-partial-config.json"
    writeFile(tempConfig, """{"url": "https://cache.example.com"}""")

    let config = loadConfig(tempConfig)
    check:
      config.url == "https://cache.example.com"
      config.timeout == DefaultTimeout
      config.enabled == false

    removeFile(tempConfig)

suite "Remote Cache Client":
  setup:
    let tempCache = getTempDir() / "test-remote-cache"
    removeDir(tempCache)
    createDir(tempCache)

    let bcm = newBinaryCacheManager(tempCache)

    var config = RemoteCacheConfig()
    config.url = "https://cache.example.com"
    config.apiKey = "test-key"
    config.timeout = 300
    config.enabled = true

    let client = newRemoteCacheClient(config, bcm)

  teardown:
    removeDir(tempCache)

  test "Create client":
    check:
      client != nil
      client.config.url == "https://cache.example.com"
      client.config.enabled == true

  test "Client configuration":
    check:
      client.config.timeout == 300
      client.config.apiKey == "test-key"

  test "Disabled client":
    var disabledConfig = RemoteCacheConfig()
    disabledConfig.enabled = false

    let disabledClient = newRemoteCacheClient(disabledConfig, bcm)

    # Should return false/none for disabled client
    check:
      disabledClient.checkAvailability() == false
      disabledClient.lookup("test", "1.0", "fp123").isNone

suite "Remote Cache Integration":
  setup:
    let tempCache = getTempDir() / "test-integration-cache"
    removeDir(tempCache)
    createDir(tempCache)

    let bcm = newBinaryCacheManager(tempCache)

  teardown:
    removeDir(tempCache)

  test "Lookup with disabled remote cache":
    var config = RemoteCacheConfig()
    config.enabled = false

    let client = newRemoteCacheClient(config, bcm)
    let result = client.lookup("vim", "9.0", "test-fp")

    check:
      result.isNone

  test "Upload with disabled remote cache":
    var config = RemoteCacheConfig()
    config.enabled = false

    let client = newRemoteCacheClient(config, bcm)

    # Create test artifact
    let testArtifact = tempCache / "test-artifact.tar.gz"
    writeFile(testArtifact, "test content")

    let result = client.upload("vim", "9.0", "test-fp", testArtifact)

    check:
      result == false

    removeFile(testArtifact)

  test "Download with local cache hit":
    # Store in local cache first
    let testArtifact = tempCache / "test-artifact.tar.gz"
    writeFile(testArtifact, "test content")

    let stored = bcm.store("vim", "9.0", "test-fp", testArtifact)
    check stored

    # Try to download - should detect local cache hit
    var config = RemoteCacheConfig()
    config.url = "https://cache.example.com"
    config.enabled = true

    let client = newRemoteCacheClient(config, bcm)
    let result = client.download("vim", "9.0", "test-fp")

    # Should return true because already in local cache
    check:
      result == true

    removeFile(testArtifact)

suite "Cache Key Generation":
  test "Generate cache key":
    let key = getCacheKey("vim", "9.0", "abc123")
    check:
      key == "vim-9.0-abc123"

  test "Cache key with empty version":
    let key = getCacheKey("vim", "", "abc123")
    check:
      key == "vim--abc123"

  test "Cache key consistency":
    let key1 = getCacheKey("vim", "9.0", "abc123")
    let key2 = getCacheKey("vim", "9.0", "abc123")
    check:
      key1 == key2

suite "Variant Fingerprint":
  test "Calculate fingerprint with USE flags":
    let fp = calculateVariantFingerprint(
      useFlags = @["python", "ruby", "lua"]
    )
    check:
      fp.len > 0

  test "Calculate fingerprint with compiler flags":
    let fp = calculateVariantFingerprint(
      cflags = "-O3 -march=native",
      ldflags = "-Wl,-O1"
    )
    check:
      fp.len > 0

  test "Calculate fingerprint with make options":
    var makeOpts = initTable[string, string]()
    makeOpts["JOBS"] = "4"
    makeOpts["VERBOSE"] = "1"

    let fp = calculateVariantFingerprint(
      makeOpts = makeOpts
    )
    check:
      fp.len > 0

  test "Fingerprint consistency":
    let fp1 = calculateVariantFingerprint(
      useFlags = @["python", "ruby"],
      cflags = "-O2"
    )
    let fp2 = calculateVariantFingerprint(
      useFlags = @["python", "ruby"],
      cflags = "-O2"
    )
    check:
      fp1 == fp2

  test "Fingerprint changes with different flags":
    let fp1 = calculateVariantFingerprint(
      useFlags = @["python"]
    )
    let fp2 = calculateVariantFingerprint(
      useFlags = @["ruby"]
    )
    check:
      fp1 != fp2

  test "Fingerprint with sorted USE flags":
    # Order shouldn't matter
    let fp1 = calculateVariantFingerprint(
      useFlags = @["python", "ruby", "lua"]
    )
    let fp2 = calculateVariantFingerprint(
      useFlags = @["lua", "python", "ruby"]
    )
    check:
      fp1 == fp2

echo "✅ All remote cache tests completed"
