#!/usr/bin/env nu

use ../core/nulib/lib_provisioning/config/schema_validator.nu *

def main [] {
  print "🧪 Configuration Validation Test Suite"
  print "======================================"
  print ""

  mut passed = 0
  mut failed = 0

  # Test 1: Schema validation with required fields
  print "Test 1: Required Fields Validation"
  let result1 = (test-required-fields)
  if $result1 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Test 2: Type validation
  print "Test 2: Type Validation"
  let result2 = (test-type-validation)
  if $result2 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Test 3: Enum validation
  print "Test 3: Enum Validation"
  let result3 = (test-enum-validation)
  if $result3 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Test 4: Range validation
  print "Test 4: Range Validation"
  let result4 = (test-range-validation)
  if $result4 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Test 5: Pattern validation
  print "Test 5: Pattern Validation"
  let result5 = (test-pattern-validation)
  if $result5 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Test 6: Deprecated fields warning
  print "Test 6: Deprecated Fields Warning"
  let result6 = (test-deprecated-fields)
  if $result6 {
    print "  ✅ PASSED"
    $passed = $passed + 1
  } else {
    print "  ❌ FAILED"
    $failed = $failed + 1
  }
  print ""

  # Summary
  print $"📊 Results: ($passed) passed, ($failed) failed"

  if $failed == 0 {
    print "✅ All tests passed!"
  } else {
    print "❌ Some tests failed"
    exit 1
  }
}

def test-required-fields [] {
  # Create temp schema
  let schema = {
    required: ["name" "version"]
    fields: {
      name: { type: "string" }
      version: { type: "string" }
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Test valid config
  let valid_config = { name: "test", version: "1.0.0" }
  let result1 = (validate-config-with-schema $valid_config $schema_file)

  # Test missing required field
  let invalid_config = { name: "test" }
  let result2 = (validate-config-with-schema $invalid_config $schema_file)

  rm $schema_file

  $result1.valid and (not $result2.valid) and ($result2.errors | length) == 1
}

def test-type-validation [] {
  let schema = {
    fields: {
      port: { type: "int" }
      name: { type: "string" }
      enabled: { type: "bool" }
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Valid types
  let valid_config = { port: 8080, name: "test", enabled: true }
  let result1 = (validate-config-with-schema $valid_config $schema_file)

  # Invalid type (string instead of int)
  let invalid_config = { port: "8080", name: "test", enabled: true }
  let result2 = (validate-config-with-schema $invalid_config $schema_file)

  rm $schema_file

  $result1.valid and (not $result2.valid)
}

def test-enum-validation [] {
  let schema = {
    fields: {
      environment: {
        type: "string"
        enum: ["dev" "staging" "prod"]
      }
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Valid enum value
  let valid_config = { environment: "prod" }
  let result1 = (validate-config-with-schema $valid_config $schema_file)

  # Invalid enum value
  let invalid_config = { environment: "production" }
  let result2 = (validate-config-with-schema $invalid_config $schema_file)

  rm $schema_file

  $result1.valid and (not $result2.valid)
}

def test-range-validation [] {
  let schema = {
    fields: {
      port: {
        type: "int"
        min: 1024
        max: 65535
      }
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Valid range
  let valid_config = { port: 8080 }
  let result1 = (validate-config-with-schema $valid_config $schema_file)

  # Below minimum
  let too_small = { port: 80 }
  let result2 = (validate-config-with-schema $too_small $schema_file)

  # Above maximum
  let too_large = { port: 70000 }
  let result3 = (validate-config-with-schema $too_large $schema_file)

  rm $schema_file

  $result1.valid and (not $result2.valid) and (not $result3.valid)
}

def test-pattern-validation [] {
  let schema = {
    fields: {
      email: {
        type: "string"
        pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
      }
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Valid email
  let valid_config = { email: "user@example.com" }
  let result1 = (validate-config-with-schema $valid_config $schema_file)

  # Invalid email
  let invalid_config = { email: "not-an-email" }
  let result2 = (validate-config-with-schema $invalid_config $schema_file)

  rm $schema_file

  $result1.valid and (not $result2.valid)
}

def test-deprecated-fields [] {
  let schema = {
    fields: {
      new_field: { type: "string" }
    }
    deprecated: ["old_field"]
    deprecated_replacements: {
      old_field: "new_field"
    }
  }

  let schema_file = (mktemp -t "schema.toml")
  $schema | to toml | save $schema_file

  # Using deprecated field
  let config = { old_field: "value" }
  let result = (validate-config-with-schema $config $schema_file)

  rm $schema_file

  $result.valid and ($result.warnings | length) == 1
}
