///|
/// Error types for cron expression parsing and validation.

///|
/// Types of validation errors that can occur in cron expressions.
pub enum CronErrorKind {
  EmptyExpression
  WrongFieldCount(Int) // actual count
  InvalidFieldValue(String) // field name
  FieldValueOutOfRange(String, Int, Int, Int) // field, value, min, max
  StepCannotBeZero(String) // field
  InvalidRange(String) // range expression
  InvalidSyntax(String) // field
  InvalidCharacter(String) // field
}

///|
/// A parsed cron error with context.
pub struct CronError {
  kind : CronErrorKind
  expression : String
}

///|
/// Convert a CronError to a human-readable string.
pub fn cron_error_to_string(err : CronError) -> String {
  let prefix = if err.expression == "" {
    ""
  } else {
    "Invalid cron expression '" + err.expression + "': "
  }
  let msg = cron_error_kind_to_string(err.kind)
  prefix + msg
}

///|
/// Convert just the error kind to a string.
fn cron_error_kind_to_string(kind : CronErrorKind) -> String {
  match kind {
    EmptyExpression => "expression is empty"
    WrongFieldCount(n) => "expected 5 fields but got " + n.to_string()
    InvalidFieldValue(f) => "invalid value in field '" + f + "'"
    FieldValueOutOfRange(f, value, min, max) =>
      "invalid " +
      f +
      " value " +
      value.to_string() +
      ": expected " +
      min.to_string() +
      ".." +
      max.to_string()
    StepCannotBeZero(f) => "step value cannot be 0 in field '" + f + "'"
    InvalidRange(f) => "invalid range syntax in field '" + f + "'"
    InvalidSyntax(f) => "invalid syntax in field '" + f + "'"
    InvalidCharacter(f) => "invalid character in field '" + f + "'"
  }
}