///|
pub fn analyze_imports(pkg_dir : String) -> ImportContext {
  let pkg_path = @path.Path(pkg_dir).join(@path.Path("moon.pkg")).0
  let content = @fs.read_file_to_string(pkg_path) catch {
    _ => return ImportContext::empty()
  }
  let imports = extract_import_strings(content)
  {
    has_cmark: imports.iter().any(fn(s) { s.contains("cmark") }),
    has_rabbita: imports.iter().any(fn(s) { s.contains("rabbita") }),
    has_mocket: imports.iter().any(fn(s) { s.contains("mocket") }),
    has_crescent: imports.iter().any(fn(s) { s.contains("crescent") }),
    has_liquid: imports.iter().any(fn(s) { s.contains("liquid") }),
    has_pug: imports.iter().any(fn(s) { s.contains("pug") }),
    is_stdlib: false,
  }
}

///|
pub fn analyze_mod_imports(project_root : String) -> ImportContext {
  let mod_path = @path.Path(project_root).join(@path.Path("moon.mod")).0
  let content = @fs.read_file_to_string(mod_path) catch {
    _ => return ImportContext::empty()
  }
  let imports = extract_import_strings(content)
  {
    has_cmark: imports.iter().any(fn(s) { s.contains("cmark") }),
    has_rabbita: imports.iter().any(fn(s) { s.contains("rabbita") }),
    has_mocket: imports.iter().any(fn(s) { s.contains("mocket") }),
    has_crescent: imports.iter().any(fn(s) { s.contains("crescent") }),
    has_liquid: imports.iter().any(fn(s) { s.contains("liquid") }),
    has_pug: imports.iter().any(fn(s) { s.contains("pug") }),
    is_stdlib: is_stdlib_module(content),
  }
}

///|
pub fn merge_imports(a : ImportContext, b : ImportContext) -> ImportContext {
  {
    has_cmark: a.has_cmark || b.has_cmark,
    has_rabbita: a.has_rabbita || b.has_rabbita,
    has_mocket: a.has_mocket || b.has_mocket,
    has_crescent: a.has_crescent || b.has_crescent,
    has_liquid: a.has_liquid || b.has_liquid,
    has_pug: a.has_pug || b.has_pug,
    is_stdlib: a.is_stdlib || b.is_stdlib,
  }
}

///|
fn is_stdlib_module(mod_content : String) -> Bool {
  let stdlib_names = [
    "moonbitlang/core", "moonbitlang/x", "moonbitlang/parser", "moonbitlang/lexer",
  ]
  for line in mod_content.split("\n") {
    let trimmed = line.to_owned().trim(chars=" \t\r")
    if trimmed.has_prefix("name") && trimmed.contains("=") {
      for name in stdlib_names {
        if trimmed.contains(name) {
          return true
        }
      }
    }
  }
  false
}

///|
fn extract_import_strings(content : String) -> Array[String] {
  let results : Array[String] = []
  let lines = content.split("\n")
  let mut in_import_block = false
  for line in lines {
    let trimmed = line.to_owned().trim(chars=" \t\r")
    if trimmed.has_prefix("import") && trimmed.contains("{") {
      in_import_block = true
      // Handle single-line: import { "pkg" }
      if trimmed.contains("}") {
        in_import_block = false
        extract_quoted_imports(trimmed.to_owned(), results)
        continue
      }
      continue
    }
    if in_import_block {
      if trimmed.contains("}") {
        in_import_block = false
        continue
      }
      let cleaned = trimmed.to_owned().trim(chars=" \t\r,\"")
      if cleaned.length() > 0 && !cleaned.has_prefix("//") {
        let cleaned_str = cleaned.to_owned()
        let pkg = if cleaned_str.contains("\"") {
          extract_quoted(cleaned_str)
        } else {
          cleaned_str
        }
        if pkg.length() > 0 {
          results.push(pkg)
        }
      }
    }
  }
  results
}

///|
fn extract_quoted_imports(line : String, results : Array[String]) -> Unit {
  let chars = line.to_array()
  let mut i = 0
  while i < chars.length() {
    if chars[i] == '"' {
      let buf = StringBuilder::new()
      i += 1
      while i < chars.length() && chars[i] != '"' {
        buf.write_char(chars[i])
        i += 1
      }
      let pkg = buf.to_string()
      if pkg.length() > 0 {
        results.push(pkg)
      }
    }
    i += 1
  }
}

///|
fn extract_quoted(s : String) -> String {
  let chars = s.to_array()
  let buf = StringBuilder::new()
  let mut in_quote = false
  for c in chars {
    if c == '"' {
      if in_quote {
        break
      }
      in_quote = true
      continue
    }
    if in_quote {
      buf.write_char(c)
    }
  }
  buf.to_string()
}