///|
fn moon_omo_config_candidates(slim : Bool) -> Array[String] {
  let dir = moon_config_dir("opencode")
  if slim {
    [
      @pathx.join(dir, "oh-my-opencode-slim.jsonc"),
      @pathx.join(dir, "oh-my-opencode-slim.json"),
    ]
  } else {
    [
      @pathx.join(dir, "oh-my-openagent.jsonc"),
      @pathx.join(dir, "oh-my-openagent.json"),
      @pathx.join(dir, "oh-my-opencode.jsonc"),
      @pathx.join(dir, "oh-my-opencode.json"),
    ]
  }
}

///|
fn moon_omo_category(slim : Bool) -> String {
  if slim {
    "omo-slim"
  } else {
    "omo"
  }
}

///|
async fn moon_omo_existing_config_path(slim : Bool) -> String? {
  for path in moon_omo_config_candidates(slim) {
    if @fsx.exists(path) {
      return Some(path)
    }
  }
  None
}

///|
async fn moon_read_omo_local_file_json(slim : Bool) -> (Json?, String?) {
  guard moon_omo_existing_config_path(slim) is Some(path) else {
    return (None, Some("OMO 配置文件不存在"))
  }
  let content = @fsx.read_file(path) catch {
    err => return (None, Some("IO 错误: \{path}: \{err}"))
  }
  match
    moon_omo_local_file_data_json_from_content(
      slim,
      path,
      moon_omo_last_modified_json(path),
      content,
    ) {
    Some(data) => (Some(data), None)
    None => (None, Some("Expected JSON object"))
  }
}

///|
fn moon_omo_last_modified_json(path : String) -> Json {
  let stat = @fsx.stat(path) catch { _ => return Json::null() }
  Json::string(@os.local_rfc3339(stat.mtime()))
}

///|
fn moon_omo_local_file_data_json_from_content(
  slim : Bool,
  path : String,
  last_modified : Json,
  content : String,
) -> Json? {
  let cleaned = moon_omo_strip_jsonc_comments(content)
  let parsed = @json.parse(cleaned) catch { _ => return None }
  guard parsed is Object(obj) else { return None }
  Some(moon_omo_local_file_data_json(slim, obj, path, last_modified))
}

///|
fn moon_omo_local_file_data_json(
  slim : Bool,
  obj : Map[String, Json],
  path : String,
  last_modified : Json,
) -> Json {
  let other : Map[String, Json] = {}
  for key in obj.keys() {
    if key != "agents" && key != "categories" {
      guard obj.get(key) is Some(value) else { continue }
      other[key] = value
    }
  }
  {
    "agents": obj.get("agents").unwrap_or(Json::null()),
    "categories": if slim {
      Json::null()
    } else {
      obj.get("categories").unwrap_or(Json::null())
    },
    "otherFields": if other.is_empty() {
      Json::null()
    } else {
      Json::object(other)
    },
    "filePath": Json::string(path),
    "lastModified": last_modified,
  }.to_json()
}

///|
fn moon_omo_strip_jsonc_comments(input : String) -> String {
  let chars = input.to_array()
  let out = StringBuilder::new()
  let mut i = 0
  let mut in_string = false
  let mut escaped = false
  while i < chars.length() {
    let ch = chars[i]
    if in_string {
      out.write_char(ch)
      if escaped {
        escaped = false
      } else if ch == '\\' {
        escaped = true
      } else if ch == '"' {
        in_string = false
      }
      i += 1
      continue
    }
    if ch == '"' {
      in_string = true
      out.write_char(ch)
      i += 1
      continue
    }
    if ch == '/' && i + 1 < chars.length() && chars[i + 1] == '/' {
      i += 2
      while i < chars.length() && chars[i] != '\n' {
        i += 1
      }
      if i < chars.length() {
        out.write_char(chars[i])
        i += 1
      }
      continue
    }
    if ch == '/' && i + 1 < chars.length() && chars[i + 1] == '*' {
      i += 2
      while i + 1 < chars.length() && !(chars[i] == '*' && chars[i + 1] == '/') {
        i += 1
      }
      if i + 1 < chars.length() {
        i += 2
      }
      continue
    }
    out.write_char(ch)
    i += 1
  }
  out.to_string()
}

///|
fn ProxyService::current_omo_provider_id(
  self : ProxyService,
  slim : Bool,
) -> String {
  let category = moon_omo_category(slim)
  let current = self.provider_router
    .current_provider_id("opencode")
    .unwrap_or("")
  guard self.provider_router.provider_by_id("opencode", current)
    is Some(provider) else {
    return ""
  }
  if provider.provider_type == Some(category) {
    current
  } else {
    ""
  }
}

///|
fn ProxyService::clear_current_omo_provider(
  self : ProxyService,
  slim : Bool,
) -> Unit {
  let category = moon_omo_category(slim)
  let current = self.provider_router
    .current_provider_id("opencode")
    .unwrap_or("")
  guard self.provider_router.provider_by_id("opencode", current)
    is Some(provider) else {
    return
  }
  if provider.provider_type == Some(category) {
    self.provider_router.current_provider_ids.remove("opencode")
  }
}

///|
async fn moon_delete_omo_config_files(slim : Bool) -> String? {
  for path in moon_omo_config_candidates(slim) {
    if @fsx.exists(path) {
      @fsx.remove(path) catch {
        err => return Some("IO 错误: \{path}: \{err}")
      }
    }
  }
  None
}

///|
async fn ProxyService::handle_disable_current_omo(
  self : ProxyService,
  w : @httpx.ResponseWriter,
  slim~ : Bool,
) -> Unit {
  self.clear_current_omo_provider(slim)
  match moon_delete_omo_config_files(slim) {
    Some(error) => write_usage_bad_request(w, error)
    None => write_usage_json(w, Json::null())
  }
}