///|
/// Convert a Sol route pattern to a Cloudflare `run_worker_first` glob.
pub fn route_pattern_to_worker_glob(path : String) -> String {
  let result = StringBuilder::new()
  let segments = path.split("/")
  let mut first = true
  for segment in segments {
    if segment.is_empty() {
      continue
    }
    if !first {
      result.write_string("/")
    }
    first = false
    if segment.has_prefix(":") {
      result.write_string("*")
    } else if segment.has_prefix("[[...") && segment.has_suffix("]]") {
      result.write_string("*")
    } else if segment.has_prefix("[...") && segment.has_suffix("]") {
      result.write_string("*")
    } else if segment.has_prefix("[") && segment.has_suffix("]") {
      result.write_string("*")
    } else {
      result.write_string(segment.to_owned())
    }
  }
  "/" + result.to_string()
}

///|
/// Extract Cloudflare `run_worker_first` patterns from Sol routes.
pub fn extract_worker_first_patterns(
  routes : Array[@router.SolRoutes],
) -> Array[String] {
  let analyzed = @router.analyze_routes(routes)
  let patterns : Array[String] = []
  for route in analyzed {
    if route.kind is @router.RouteKind::Dynamic {
      let pattern = route_pattern_to_worker_glob(route.pattern)
      if !patterns.contains(pattern) {
        patterns.push(pattern)
      }
    }
  }
  patterns.sort_by(compare_strings_lex)
  patterns
}

///|
fn compare_strings_lex(a : String, b : String) -> Int {
  let a_chars = a.to_array()
  let b_chars = b.to_array()
  let n = if a_chars.length() < b_chars.length() {
    a_chars.length()
  } else {
    b_chars.length()
  }
  for i = 0; i < n; i = i + 1 {
    if a_chars[i] < b_chars[i] {
      return -1
    }
    if a_chars[i] > b_chars[i] {
      return 1
    }
  }
  if a_chars.length() < b_chars.length() {
    -1
  } else if a_chars.length() > b_chars.length() {
    1
  } else {
    0
  }
}

///|
/// Generate a Wrangler `assets` config fragment for Cloudflare Workers.
pub fn generate_wrangler_assets_config(
  routes : Array[@router.SolRoutes],
  output_dir : String,
) -> String {
  let patterns = extract_worker_first_patterns(routes)
  let output_dir_json = ffi_js_string_literal(output_dir)
  if patterns.is_empty() {
    return "{\n  \"directory\": \{output_dir_json},\n  \"html_handling\": \"auto-trailing-slash\",\n  \"not_found_handling\": \"404-page\"\n}"
  }

  let patterns_json = StringBuilder::new()
  patterns_json.write_string("[")
  for i, pattern in patterns {
    if i > 0 {
      patterns_json.write_string(", ")
    }
    patterns_json.write_string(ffi_js_string_literal(pattern))
  }
  patterns_json.write_string("]")
  "{\n  \"directory\": \{output_dir_json},\n  \"html_handling\": \"auto-trailing-slash\",\n  \"not_found_handling\": \"single-page-application\",\n  \"run_worker_first\": \{patterns_json.to_string()}\n}"
}