// Copyright (c) 2026 colmugx
// SPDX-License-Identifier: Apache-2.0

///|
#deprecated("Temporary General_Category normalization: recheck moonbitlang/regexp before removing", skip_current_package=true)
fn unicode_property(
  pattern : String,
  start : Int32,
  in_class : Bool,
) -> (String, Int32) raise PatternError {
  guard start + 2 < pattern.length() && pattern[start + 2] == '{' else {
    raise NotSupported("malformed Unicode property escape")
  }
  let mut end = start + 3
  while end < pattern.length() && pattern[end] != '}' {
    end += 1
  }
  guard end < pattern.length() else {
    raise NotSupported("unterminated Unicode property escape")
  }
  let name = pattern[start + 3:end].to_owned()
  let bare = if name.has_prefix("General_Category=") {
    name[17:].to_owned()
  } else {
    name
  }
  let negated = pattern[start + 1] == 'P'
  if in_class && negated {
    raise NotSupported("negated Unicode property inside a class is unsupported")
  }
  if in_class &&
    (
      (start > 0 && pattern[start - 1] == '-') ||
      (end + 1 < pattern.length() && pattern[end + 1] == '-')
    ) {
    raise NotSupported(
      "Unicode properties used as range endpoints are unsupported",
    )
  }
  ("\\" + (if negated { "P" } else { "p" }) + "{" + bare + "}", end + 1)
}

///|
// Exactly ^(body)\1$: there is a single capture and no surrounding context.
// Splitting in equal halves removes capture-choice ambiguity; nested captures,
// assertions and context-sensitive anchors are explicitly refused.
#deprecated("Temporary anchored backreference profile: recheck moonbitlang/regexp before removing", skip_current_package=true)
fn repeated_capture_body(pattern : String) -> String? raise PatternError {
  if !pattern.has_prefix("^(") ||
    pattern.has_prefix("^(?") ||
    !pattern.has_suffix(")\\1$") {
    return None
  }
  let mut depth = 1
  let mut in_class = false
  let mut index = 2
  while index < pattern.length() {
    let c = char_at(pattern, index)
    if c == '\\' && index + 1 < pattern.length() {
      let next = char_at(pattern, index + 1)
      if next is ('0'..<='9') ||
        next == 'k' ||
        (!in_class && (next == 'b' || next == 'B')) {
        raise NotSupported(
          "nested backreferences or boundaries in repeated captures are unsupported",
        )
      }
      index += 1 + char_width(next)
      continue
    }
    if c == '[' && !in_class {
      in_class = true
    } else if c == ']' && in_class {
      in_class = false
    }
    if !in_class {
      if c == '^' || c == '$' {
        raise NotSupported("anchors inside repeated captures are unsupported")
      }
      if c == '(' {
        if !pattern[index:].has_prefix("(?:") {
          raise NotSupported(
            "nested captures or assertions in repeated captures are unsupported",
          )
        }
        depth += 1
      } else if c == ')' {
        depth -= 1
        if depth == 0 {
          if index != pattern.length() - 4 {
            return None
          }
          return Some(pattern[2:index].to_owned())
        }
      }
    }
    index += char_width(c)
  }
  None
}

///|
#deprecated("Temporary anchored backreference matcher: recheck moonbitlang/regexp before removing", skip_current_package=true)
fn repeated_capture_matches(expression : @regexp.Regexp, text : String) -> Bool {
  if text.length() % 2 != 0 {
    return false
  }
  let middle = text.length() / 2
  guard text.get_view(start=0, end=middle) is Some(first) &&
    text.get_view(start=middle) is Some(second) else {
    return false
  }
  first == second && expression.execute(first).matched()
}