///|
/// Common string utilities for Mars framework

///|
/// Extract substring from start to end index
pub fn substring(s : String, start : Int, end : Int) -> String {
  let buf = StringBuilder::new()
  for i, c in s {
    if i >= start && i < end {
      buf.write_char(c)
    }
  }
  buf.to_string()
}

///|
/// Extract substring from start to end of string
pub fn substring_from(s : String, start : Int) -> String {
  let buf = StringBuilder::new()
  for i, c in s {
    if i >= start {
      buf.write_char(c)
    }
  }
  buf.to_string()
}

///|
/// Split string by separator character
pub fn split_by_char(s : String, sep : Char) -> Array[String] {
  let result : Array[String] = []
  let current = StringBuilder::new()
  for c in s {
    if c == sep {
      result.push(current.to_string())
      current.reset()
    } else {
      current.write_char(c)
    }
  }
  result.push(current.to_string())
  result
}

///|
/// Find first occurrence of character in string, returns -1 if not found
pub fn find_char(s : String, c : Char) -> Int {
  for i, ch in s {
    if ch == c {
      return i
    }
  }
  -1
}

///|
/// Trim whitespace from both ends of string
pub fn trim(s : String) -> String {
  let chars : Array[Char] = []
  for c in s {
    chars.push(c)
  }
  // Find start (skip leading whitespace)
  let mut start = 0
  while start < chars.length() && is_whitespace(chars[start]) {
    start = start + 1
  }
  // Find end (skip trailing whitespace)
  let mut end = chars.length()
  while end > start && is_whitespace(chars[end - 1]) {
    end = end - 1
  }
  // Build result
  let buf = StringBuilder::new()
  for i in start.. Bool {
  c == ' ' || c == '\t' || c == '\n' || c == '\r'
}

///|
/// Strip query string from path (everything from first '?' onwards)
pub fn strip_query_string(path : String) -> String {
  let buf = StringBuilder::new()
  for c in path {
    if c == '?' {
      break
    }
    buf.write_char(c)
  }
  buf.to_string()
}

///|
/// URL decode a string (handles %XX and + encoding)
pub fn url_decode(s : String) -> String {
  let buf = StringBuilder::new()
  let chars : Array[Char] = []
  for c in s {
    chars.push(c)
  }
  let mut i = 0
  while i < chars.length() {
    let c = chars[i]
    if c == '%' && i + 2 < chars.length() {
      let high = hex_to_int(chars[i + 1])
      let low = hex_to_int(chars[i + 2])
      if high >= 0 && low >= 0 {
        buf.write_char(((high << 4) | low).unsafe_to_char())
        i = i + 3
        continue
      }
    } else if c == '+' {
      buf.write_char(' ')
      i = i + 1
      continue
    }
    buf.write_char(c)
    i = i + 1
  }
  buf.to_string()
}

///|
/// Convert hex character to integer, returns -1 for invalid
pub fn hex_to_int(c : Char) -> Int {
  match c {
    '0'..='9' => c.to_int() - '0'.to_int()
    'a'..='f' => c.to_int() - 'a'.to_int() + 10
    'A'..='F' => c.to_int() - 'A'.to_int() + 10
    _ => -1
  }
}

///|
/// Convert character to lowercase
pub fn char_to_lower(c : Char) -> Char {
  match c {
    'A'..='Z' => (c.to_int() + 32).unsafe_to_char()
    _ => c
  }
}

///|
/// Convert string to lowercase
pub fn to_lower(s : String) -> String {
  let buf = StringBuilder::new()
  for c in s {
    buf.write_char(char_to_lower(c))
  }
  buf.to_string()
}