# Orchestrator Validators
# Queue, batch, workflow, and orchestration-specific validation logic

let constraints = import "../constraints/constraints.toml" in
let common = import "./common-validator.ncl" in

{
  # Validate worker count within constraints
  ValidWorkers = fun workers =>
    common.ValidRange
      constraints.orchestrator.workers.min
      constraints.orchestrator.workers.max
      workers,

  # Validate max concurrent tasks in queue
  ValidConcurrentTasks = fun tasks =>
    common.ValidRange
      constraints.orchestrator.queue.concurrent_tasks.min
      constraints.orchestrator.queue.concurrent_tasks.max
      tasks,

  # Validate retry attempts
  ValidRetryAttempts = fun attempts =>
    common.ValidRange
      constraints.orchestrator.queue.retry_attempts.min
      constraints.orchestrator.queue.retry_attempts.max
      attempts,

  # Validate retry delay in milliseconds
  ValidRetryDelay = fun delay =>
    common.ValidRange
      constraints.orchestrator.queue.retry_delay.min
      constraints.orchestrator.queue.retry_delay.max
      delay,

  # Validate task timeout in milliseconds
  ValidTaskTimeout = fun timeout =>
    common.ValidRange
      constraints.orchestrator.queue.task_timeout.min
      constraints.orchestrator.queue.task_timeout.max
      timeout,

  # Validate batch parallel limit
  ValidParallelLimit = fun limit =>
    common.ValidRange
      constraints.orchestrator.batch.parallel_limit.min
      constraints.orchestrator.batch.parallel_limit.max
      limit,

  # Validate batch operation timeout in milliseconds
  ValidBatchOperationTimeout = fun timeout =>
    common.ValidRange
      constraints.orchestrator.batch.operation_timeout.min
      constraints.orchestrator.batch.operation_timeout.max
      timeout,

  # Validate checkpoint interval (task count)
  ValidCheckpointInterval = fun interval =>
    if interval < 1 then
      std.contract.blame_with_message "Checkpoint interval must be >= 1 task" interval
    else if interval > 10000 then
      std.contract.blame_with_message "Checkpoint interval must be <= 10000 tasks" interval
    else
      interval,

  # Validate max checkpoints to retain
  ValidMaxCheckpoints = fun count =>
    if count < 1 then
      std.contract.blame_with_message "Max checkpoints must be >= 1" count
    else if count > 100 then
      std.contract.blame_with_message "Max checkpoints must be <= 100" count
    else
      count,

  # Validate rollback max depth
  ValidRollbackDepth = fun depth =>
    if depth < 1 then
      std.contract.blame_with_message "Rollback depth must be >= 1" depth
    else if depth > 100 then
      std.contract.blame_with_message "Rollback depth must be <= 100" depth
    else
      depth,

  # Validate max concurrent extensions
  ValidMaxConcurrentExtensions = fun count =>
    common.ValidRange
      constraints.orchestrator.extensions.max_concurrent.min
      constraints.orchestrator.extensions.max_concurrent.max
      count,

  # Validate extension discovery interval
  ValidExtensionDiscoveryInterval = fun interval =>
    if interval < 10 then
      std.contract.blame_with_message "Extension discovery interval must be >= 10 seconds" interval
    else if interval > 3600 then
      std.contract.blame_with_message "Extension discovery interval must be <= 3600 seconds" interval
    else
      interval,

  # Validate dead letter queue max size
  ValidDlqMaxSize = fun size =>
    if size < 10 then
      std.contract.blame_with_message "DLQ max size must be >= 10" size
    else if size > 100000 then
      std.contract.blame_with_message "DLQ max size must be <= 100000" size
    else
      size,

  # Validate workflow is structurally sound
  ValidWorkflowStructure = fun workflow =>
    if workflow == null then
      std.contract.blame_with_message "Workflow cannot be null" workflow
    else
      workflow,

  # Validate task definition is complete
  ValidTaskDefinition = fun task =>
    if task.name == null || task.name == "" then
      std.contract.blame_with_message "Task must have a non-empty name" task
    else
      task,
}
