///|
priv suberror CliError {
  CommandFailed(String)
} derive(Debug)

///|
priv struct GeneratedTransaction {
  package_dir : String
  catalog_dir : String
  code : String
  package_manifest : String
  generation_manifest : String
  catalog_names : Array[String]
  catalog_contents : Array[String]
}

///|
priv struct TransactionState {
  package_dir : String
  catalog_dir : String
  package_stage : String
  catalog_stage : String
  package_backup : String
  catalog_backup : String
  had_package : Bool
  had_catalogs : Bool
}

///|
priv struct OwnershipManifest {
  files : Array[String]
}

///|
#cfg(target="native")
extern "C" fn exit(code : Int32) = "exit"

///|
#cfg(target="wasm")
fn exit(code : UInt32) = "wasi_snapshot_preview1" "proc_exit"

///|
fn[T] cli_fail(message : String) -> T raise CliError {
  raise CommandFailed(message)
}

///|
async fn[T] die(message : String) -> T {
  @stdio.stderr.write("\{message}\n") catch {
    _ => ()
  }
  exit(1)
  panic()
}

///|
const DIAGNOSTIC_ENVELOPE : String = "__LAMPCLAW_I18N_DIAGNOSTIC_V1__\n"

///|
const DIAGNOSTIC_HUMAN_SEPARATOR : String = "\n__LAMPCLAW_I18N_HUMAN_V1__\n"

///|
fn diagnostic_envelope(diagnostic : @generator.Diagnostic) -> String {
  DIAGNOSTIC_ENVELOPE +
  diagnostic.to_json_string() +
  DIAGNOSTIC_HUMAN_SEPARATOR +
  diagnostic.to_human_string()
}

///|
fn as_path(value : String) -> @path.Path {
  @path.Path(value)
}

///|
fn resolved_path(value : String) -> String {
  as_path(value).resolve().to_string()
}

///|
fn path_dirname(value : String) -> String {
  as_path(value).dirname().to_string()
}

///|
fn path_basename(value : String) -> String {
  as_path(value).basename().to_owned()
}

///|
fn path_join(left : String, right : String) -> String {
  as_path(left).join(as_path(right)).to_string()
}

///|
fn is_root_path(value : String) -> Bool {
  let path = as_path(value)
  path.dirname() == path
}

///|
fn path_contains(parent : String, child : String) -> Bool {
  if parent == child {
    return true
  }
  let relative = as_path(child).relative(base=as_path(parent))
  let text = relative.to_string()
  if text.is_empty() || relative.is_absolute() {
    return false
  }
  text != ".." && !text.has_prefix("../") && !text.has_prefix("..\\")
}

///|
fn valid_generated_filename(name : String) -> Bool {
  if !name.has_suffix(".json") || name.length() <= ".json".length() {
    return false
  }
  let chars = name.to_array()
  guard (match chars[0] {
    'a'..<='z' | 'A'..<='Z' | '0'..<='9' => true
    _ => false
  }) else {
    return false
  }
  for char in chars {
    guard (match char {
      'a'..<='z' | 'A'..<='Z' | '0'..<='9' | '.' | '_' | '-' => true
      _ => false
    }) else {
      return false
    }
  }
  true
}

///|
fn valid_nonce(nonce : String) -> Bool {
  if nonce.is_empty() || nonce.length() > 128 {
    return false
  }
  for char in nonce.to_array() {
    guard (match char {
      'a'..<='z' | 'A'..<='Z' | '0'..<='9' | '-' => true
      _ => false
    }) else {
      return false
    }
  }
  true
}

///|
fn transaction_nonce(value : String, target : String, kind : String) -> String? {
  if resolved_path(value) != value ||
    path_dirname(value) != path_dirname(target) {
    return None
  }
  let prefix = ".\{path_basename(target)}.\{kind}-"
  let name = path_basename(value)
  if !name.has_prefix(prefix) {
    return None
  }
  let nonce = name[prefix.length():].to_owned()
  if valid_nonce(nonce) {
    Some(nonce)
  } else {
    None
  }
}

///|
async fn file_kind(path : String) -> @fs.FileKind raise CliError {
  try @fs.kind(path, follow_symlink=false) catch {
    err => cli_fail("cannot inspect \{path}: \{err}")
  } noraise {
    value => value
  }
}

///|
async fn file_exists(path : String) -> Bool raise CliError {
  try @fs.exists(path) catch {
    err => cli_fail("cannot inspect \{path}: \{err}")
  } noraise {
    value => value
  }
}

///|
async fn ensure_directory(path : String) -> Unit raise CliError {
  for attempt = 0; attempt < 8; attempt = attempt + 1 {
    if file_exists(path) {
      if !(file_kind(path) is Directory) {
        cli_fail("\{path} is not a directory")
      }
      return
    }
    try @fs.mkdir(path, recursive=true) catch {
      err => {
        // Concurrent recursive creators can expose an intermediate state in
        // which a parent exists but the target does not yet. Retry only this
        // bounded first-use race; a non-directory target fails immediately.
        if file_exists(path) {
          if !(file_kind(path) is Directory) {
            cli_fail("\{path} is not a directory")
          }
          return
        }
        if attempt == 7 {
          cli_fail("cannot create directory \{path}: \{err}")
        }
        @async.pause()
      }
    } noraise {
      _ => return
    }
  }
  cli_fail("cannot create directory \{path}")
}

///|
async fn regular_file_size(path : String) -> Int64 raise CliError {
  if !(file_kind(path) is Regular) {
    cli_fail("cannot read \{path}: not a regular file")
  }
  let file = try @fs.open(path, mode=ReadOnly) catch {
    err => cli_fail("cannot open \{path}: \{err}")
  } noraise {
    value => value
  }
  defer file.close()
  try file.size() catch {
    err => cli_fail("cannot inspect \{path}: \{err}")
  } noraise {
    value => value
  }
}

///|
async fn read_file(path : String) -> String raise CliError {
  read_file_limited(path, @generator.I18N_MAX_TOTAL_LOCALE_BYTES)
}

///|
async fn read_file_limited(
  path : String,
  max_bytes : Int32,
) -> String raise CliError {
  if max_bytes < 0 {
    cli_fail("invalid negative byte limit for \{path}")
  }
  if !(file_kind(path) is Regular) {
    cli_fail("cannot read \{path}: not a regular file")
  }
  let file = try @fs.open(path, mode=ReadOnly) catch {
    err => cli_fail("cannot open \{path}: \{err}")
  } noraise {
    value => value
  }
  defer file.close()
  let size = try file.size() catch {
    err => cli_fail("cannot inspect \{path}: \{err}")
  } noraise {
    value => value
  }
  if size > max_bytes.to_int64() {
    cli_fail("file exceeds the \{max_bytes}-byte limit: \{path}")
  }
  let bytes = try file.read_exactly_at(size.to_int(), position=0L) catch {
    err => cli_fail("cannot read \{path}: \{err}")
  } noraise {
    value => value
  }
  try @utf8.decode(bytes) catch {
    _ => cli_fail("cannot read \{path}: invalid UTF-8 encoded data")
  } noraise {
    value => value
  }
}

///|
async fn write_file(path : String, content : String) -> Unit raise CliError {
  let parent = path_dirname(resolved_path(path))
  ensure_directory(parent)
  try
    @fs.write_file(path, content, create_mode=CreateOrTruncate, sync=Full)
  catch {
    err => cli_fail("cannot write \{path}: \{err}")
  } noraise {
    _ => ()
  }
}

///|
async fn write_new_file(
  path : String,
  content : String,
  permission : Int32,
) -> Unit raise CliError {
  try
    @fs.write_file(path, content, create_mode=CreateNew, permission~, sync=Full)
  catch {
    err => cli_fail("cannot create \{path}: \{err}")
  } noraise {
    _ => ()
  }
}

///|
async fn read_dir(path : String) -> Array[String] raise CliError {
  if !(file_kind(path) is Directory) {
    cli_fail("cannot read directory \{path}: not a directory")
  }
  try @fs.readdir(path, include_hidden=true, sort=true) catch {
    err => cli_fail("cannot read directory \{path}: \{err}")
  } noraise {
    value => value
  }
}

///|
async fn remove_path(path : String) -> Unit raise CliError {
  if !file_exists(path) {
    return
  }
  let kind = file_kind(path)
  if kind is Directory {
    try @fs.rmdir(path, recursive=true) catch {
      err => cli_fail("cannot remove directory \{path}: \{err}")
    } noraise {
      _ => ()
    }
  } else {
    try @fs.remove(path) catch {
      err => cli_fail("cannot remove \{path}: \{err}")
    } noraise {
      _ => ()
    }
  }
}

///|
async fn rename_path(from : String, to : String) -> Unit raise CliError {
  try @fs.rename(from, to, replace=false) catch {
    err => cli_fail("cannot rename \{from} to \{to}: \{err}")
  } noraise {
    _ => ()
  }
}

///|
fn json_string_field(object : Map[String, Json], name : String) -> String? {
  match object.get(name) {
    Some(String(value)) => Some(value)
    _ => None
  }
}

///|
fn json_bool_field(object : Map[String, Json], name : String) -> Bool? {
  match object.get(name) {
    Some(True) => Some(true)
    Some(False) => Some(false)
    _ => None
  }
}

///|
fn json_int_field(object : Map[String, Json], name : String) -> Int32? {
  match object.get(name) {
    Some(Number(value, ..)) => {
      let integer = value.to_int()
      if integer.to_double() == value {
        Some(integer)
      } else {
        None
      }
    }
    _ => None
  }
}

///|
#warnings("-deprecated")
fn parse_ownership_manifest(
  source : String,
  expected_kind : String,
) -> OwnershipManifest raise CliError {
  let json = try @json.parse(source, max_nesting_depth=16) catch {
    _ => cli_fail("invalid generated-directory ownership manifest JSON")
  } noraise {
    value => value
  }
  guard json is Object(object) else {
    cli_fail("invalid generated-directory ownership manifest")
  }
  guard json_int_field(object, "version") is Some(version) &&
    (version == 1 || version == 2) &&
    json_string_field(object, "generator") is Some("lampclaw/i18n") &&
    json_string_field(object, "kind") is Some(kind) &&
    kind == expected_kind &&
    object.get("files") is Some(Array(raw_files)) else {
    cli_fail("invalid generated-directory ownership manifest")
  }
  let files : Array[String] = []
  for raw in raw_files {
    guard raw is String(name) else {
      cli_fail("invalid generated-directory ownership manifest")
    }
    if files.contains(name) {
      cli_fail("invalid generated-directory ownership manifest")
    }
    files.push(name)
  }
  if kind == "package" {
    let legacy = files.length() == 2 &&
      files.contains("generated.mbt") &&
      files.contains("moon.pkg")
    let current = files.length() == 3 &&
      files.contains("generated.mbt") &&
      files.contains("moon.pkg") &&
      files.contains("generation-manifest.json")
    if !legacy && !current {
      cli_fail("invalid generated-directory ownership manifest")
    }
  } else {
    for file in files {
      if !valid_generated_filename(file) {
        cli_fail("invalid generated-directory ownership manifest")
      }
    }
  }
  { files, }
}

///|
async fn verify_owned_entries(
  directory : String,
  kind : String,
  entries : Array[String],
  manifest : OwnershipManifest,
) -> Unit raise CliError {
  let expected = manifest.files.copy()
  expected.push(".lampclaw-i18n.json")
  if kind == "package" {
    expected.push("pkg.generated.mbti")
  }
  for entry in entries {
    let entry_path = path_join(directory, entry)
    if !expected.contains(entry) {
      cli_fail("refusing to replace unowned file: \{entry_path}")
    }
    if !(file_kind(entry_path) is Regular) {
      cli_fail("refusing to replace non-file generated artifact: \{entry_path}")
    }
    let limit = if entry == ".lampclaw-i18n.json" {
      64 * 1024
    } else if kind == "package" {
      @generator.I18N_MAX_GENERATED_CODE_BYTES
    } else {
      @runtime.CATALOG_MAX_SOURCE_BYTES
    }
    if regular_file_size(entry_path) > limit.to_int64() {
      cli_fail("generated artifact exceeds size limit: \{entry_path}")
    }
  }
}

///|
async fn verify_unowned_package(
  directory : String,
  entries : Array[String],
) -> Unit raise CliError {
  let allowed = [
    "generated.mbt", "moon.pkg", "generation-manifest.json", "pkg.generated.mbti",
  ]
  for entry in entries {
    let entry_path = path_join(directory, entry)
    if !allowed.contains(entry) ||
      !(file_kind(entry_path) is Regular) ||
      regular_file_size(entry_path) >
      @generator.I18N_MAX_GENERATED_CODE_BYTES.to_int64() {
      cli_fail("refusing to adopt invalid generated artifact: \{entry_path}")
    }
    if entry == "generated.mbt" || entry == "moon.pkg" {
      let source = read_file_limited(
        entry_path,
        @generator.I18N_MAX_GENERATED_CODE_BYTES,
      )
      if !is_generated_content(source) {
        cli_fail("refusing to overwrite unowned i18n file: \{entry_path}")
      }
    } else if entry == "generation-manifest.json" &&
      !looks_like_generation_manifest(
        read_file_limited(entry_path, 1024 * 1024),
      ) {
      cli_fail("refusing to overwrite unowned i18n file: \{entry_path}")
    }
  }
}

///|
#warnings("-deprecated")
fn looks_like_generation_manifest(source : String) -> Bool {
  let json = try @json.parse(source, max_nesting_depth=16) catch {
    _ => return false
  } noraise {
    value => value
  }
  guard json is Object(object) else { return false }
  json_int_field(object, "manifestVersion") is Some(1) &&
  json_string_field(object, "generator") is Some("lampclaw/i18n")
}

///|
#warnings("-deprecated")
fn looks_like_generated_catalog(source : String) -> Bool {
  let json = try @json.parse(source, max_nesting_depth=64) catch {
    _ => return false
  } noraise {
    value => value
  }
  guard json is Object(object) else { return false }
  if json_int_field(object, "manifestVersion") is Some(1) &&
    json_string_field(object, "generator") is Some("lampclaw/i18n") &&
    object.get("chunks") is Some(Array(_)) {
    return true
  }
  guard object.get("catalogVersion") is Some(Number(_, ..)) else {
    return false
  }
  object.get("contractHash") is Some(String(_)) ||
  object.get("schemaHash") is Some(String(_))
}

///|
async fn verify_unowned_catalogs(
  directory : String,
  entries : Array[String],
) -> Unit raise CliError {
  for entry in entries {
    let entry_path = path_join(directory, entry)
    if !valid_generated_filename(entry) ||
      !(file_kind(entry_path) is Regular) ||
      regular_file_size(entry_path) >
      @runtime.CATALOG_MAX_SOURCE_BYTES.to_int64() {
      cli_fail("refusing to adopt invalid generated artifact: \{entry_path}")
    }
    if !looks_like_generated_catalog(
        read_file_limited(entry_path, @runtime.CATALOG_MAX_SOURCE_BYTES),
      ) {
      cli_fail("refusing to adopt non-catalog file: \{entry_path}")
    }
  }
}

///|
async fn verify_generated_directory(
  directory : String,
  kind : String,
) -> Unit raise CliError {
  if !file_exists(directory) {
    return
  }
  if !(file_kind(directory) is Directory) {
    cli_fail("\{directory} is not a directory")
  }
  let entries = read_dir(directory)
  let owner_path = path_join(directory, ".lampclaw-i18n.json")
  if file_exists(owner_path) {
    let manifest = parse_ownership_manifest(
      read_file_limited(owner_path, 64 * 1024),
      kind,
    ) catch {
      CommandFailed(_) =>
        cli_fail(
          "invalid generated-directory ownership manifest: \{owner_path}",
        )
    }
    verify_owned_entries(directory, kind, entries, manifest)
  } else if kind == "package" {
    verify_unowned_package(directory, entries)
  } else {
    verify_unowned_catalogs(directory, entries)
  }
}

///|
fn transaction_state_json(state : TransactionState) -> String {
  Json::object({
    "version": Json::number(2.0),
    "pkg": Json::string(state.package_dir),
    "catalogs": Json::string(state.catalog_dir),
    "pkgStage": Json::string(state.package_stage),
    "catStage": Json::string(state.catalog_stage),
    "pkgBackup": Json::string(state.package_backup),
    "catBackup": Json::string(state.catalog_backup),
    "hadPkg": Json::boolean(state.had_package),
    "hadCatalogs": Json::boolean(state.had_catalogs),
  }).stringify(indent=2) +
  "\n"
}

///|
#warnings("-deprecated")
fn parse_transaction_state(
  source : String,
  package_dir : String,
  catalog_dir : String,
) -> TransactionState raise CliError {
  let json = try @json.parse(source, max_nesting_depth=16) catch {
    _ => cli_fail("invalid i18n transaction journal")
  } noraise {
    value => value
  }
  guard json is Object(object) else {
    cli_fail("invalid i18n transaction journal")
  }
  guard json_int_field(object, "version") is Some(version) &&
    (version == 1 || version == 2) &&
    json_string_field(object, "pkg") is Some(pkg) &&
    json_string_field(object, "catalogs") is Some(catalogs) &&
    json_string_field(object, "pkgStage") is Some(pkg_stage) &&
    json_string_field(object, "catStage") is Some(cat_stage) &&
    json_string_field(object, "pkgBackup") is Some(pkg_backup) &&
    json_string_field(object, "catBackup") is Some(cat_backup) &&
    json_bool_field(object, "hadPkg") is Some(had_pkg) &&
    json_bool_field(object, "hadCatalogs") is Some(had_catalogs) &&
    pkg == package_dir &&
    catalogs == catalog_dir &&
    transaction_nonce(pkg_stage, pkg, "stage") is Some(nonce) &&
    transaction_nonce(cat_stage, catalogs, "stage") is Some(cat_nonce) &&
    transaction_nonce(pkg_backup, pkg, "backup") is Some(pkg_backup_nonce) &&
    transaction_nonce(cat_backup, catalogs, "backup") is Some(cat_backup_nonce) &&
    nonce == cat_nonce &&
    nonce == pkg_backup_nonce &&
    nonce == cat_backup_nonce else {
    cli_fail("invalid i18n transaction journal")
  }
  {
    package_dir: pkg,
    catalog_dir: catalogs,
    package_stage: pkg_stage,
    catalog_stage: cat_stage,
    package_backup: pkg_backup,
    catalog_backup: cat_backup,
    had_package: had_pkg,
    had_catalogs,
  }
}

///|
async fn validate_transaction_artifact(path : String) -> Unit raise CliError {
  let kind = try @fs.kind(path, follow_symlink=false) catch {
    _ => None
  } noraise {
    kind => Some(kind)
  }
  match kind {
    Some(Directory) | None => ()
    Some(_) => cli_fail("invalid i18n transaction artifact: \{path}")
  }
}

///|
async fn settle_transaction(
  state : TransactionState,
  journal : String,
) -> Bool raise CliError {
  for
    artifact in [
      state.package_stage,
      state.catalog_stage,
      state.package_backup,
      state.catalog_backup,
    ] {
    validate_transaction_artifact(artifact)
  }
  let committed = !file_exists(state.package_stage) &&
    !file_exists(state.catalog_stage) &&
    file_exists(state.package_dir) &&
    file_exists(state.catalog_dir)
  if !committed {
    if file_exists(state.package_backup) {
      remove_path(state.package_dir)
      rename_path(state.package_backup, state.package_dir)
    } else if !state.had_package {
      remove_path(state.package_dir)
    }
    if file_exists(state.catalog_backup) {
      remove_path(state.catalog_dir)
      rename_path(state.catalog_backup, state.catalog_dir)
    } else if !state.had_catalogs {
      remove_path(state.catalog_dir)
    }
  }
  remove_path(state.package_stage)
  remove_path(state.catalog_stage)
  remove_path(state.package_backup)
  remove_path(state.catalog_backup)
  remove_path(journal)
  committed
}

///|
async fn recover_transaction(
  journal : String,
  package_dir : String,
  catalog_dir : String,
) -> Unit raise CliError {
  if !file_exists(journal) {
    return
  }
  let state = parse_transaction_state(
    read_file_limited(journal, 64 * 1024),
    package_dir,
    catalog_dir,
  ) catch {
    CommandFailed(_) => cli_fail("invalid i18n transaction journal: \{journal}")
  }
  ignore(settle_transaction(state, journal))
}

///|
fn ownership_manifest(kind : String, files : Array[String]) -> String {
  let quoted = files.map(file => "\"\{file}\"").join(", ")
  "{\n  \"version\": 2,\n  \"generator\": \"lampclaw/i18n\",\n  \"kind\": \"\{kind}\",\n  \"files\": [\{quoted}]\n}\n"
}

///|
fn transaction_journal(package_dir : String) -> String {
  path_join(
    path_dirname(package_dir),
    ".\{path_basename(package_dir)}.lampclaw-journal.json",
  )
}

///|
fn generation_lock_directory_from(
  environment : Map[String, String],
  current_directory : String,
) -> String {
  match environment.get("LAMPCLAW_I18N_STATE_DIR") {
    Some(value) if !value.trim().is_empty() => return resolved_path(value)
    _ => ()
  }
  match environment.get("XDG_CACHE_HOME") {
    Some(value) if !value.trim().is_empty() =>
      return path_join(resolved_path(value), "lampclaw-i18n/locks")
    _ => ()
  }
  match environment.get("LOCALAPPDATA") {
    Some(value) if !value.trim().is_empty() =>
      return path_join(resolved_path(value), "lampclaw/i18n/locks")
    _ => ()
  }
  for name in ["HOME", "USERPROFILE"] {
    match environment.get(name) {
      Some(value) if !value.trim().is_empty() =>
        return path_join(resolved_path(value), ".cache/lampclaw-i18n/locks")
      _ => ()
    }
  }
  for name in ["TMPDIR", "TEMP", "TMP"] {
    match environment.get(name) {
      Some(value) if !value.trim().is_empty() =>
        return path_join(resolved_path(value), "lampclaw-i18n/locks")
      _ => ()
    }
  }
  path_join(current_directory, ".lampclaw-i18n-locks")
}

///|
fn generation_lock_directory() -> String {
  generation_lock_directory_from(@env.get_env_vars(), resolved_path("."))
}

///|
fn transaction_lock_path(directory : String, lock_directory : String) -> String {
  let digest = @crypto.bytes_to_hex_string(
    @crypto.sha256(@utf8.encode(resolved_path(directory))),
  )
  path_join(lock_directory, "\{digest}.lampclaw.lock")
}

///|
fn make_transaction_state(
  transaction : GeneratedTransaction,
  nonce : String,
) -> TransactionState {
  let package_parent = path_dirname(transaction.package_dir)
  let catalog_parent = path_dirname(transaction.catalog_dir)
  let package_name = path_basename(transaction.package_dir)
  let catalog_name = path_basename(transaction.catalog_dir)
  {
    package_dir: transaction.package_dir,
    catalog_dir: transaction.catalog_dir,
    package_stage: path_join(package_parent, ".\{package_name}.stage-\{nonce}"),
    catalog_stage: path_join(catalog_parent, ".\{catalog_name}.stage-\{nonce}"),
    package_backup: path_join(
      package_parent,
      ".\{package_name}.backup-\{nonce}",
    ),
    catalog_backup: path_join(
      catalog_parent,
      ".\{catalog_name}.backup-\{nonce}",
    ),
    had_package: false,
    had_catalogs: false,
  }
}

///|
async fn allocate_transaction_state(
  transaction : GeneratedTransaction,
) -> TransactionState raise CliError {
  for attempt = 0; attempt < 100; attempt = attempt + 1 {
    let nonce = "\{@async.now()}-\{attempt}"
    let candidate = make_transaction_state(transaction, nonce)
    if !file_exists(candidate.package_stage) &&
      !file_exists(candidate.catalog_stage) &&
      !file_exists(candidate.package_backup) &&
      !file_exists(candidate.catalog_backup) {
      return {
        ..candidate,
        had_package: file_exists(transaction.package_dir),
        had_catalogs: file_exists(transaction.catalog_dir),
      }
    }
  }
  cli_fail("cannot allocate unique i18n transaction paths")
}

///|
async fn stage_transaction(
  transaction : GeneratedTransaction,
  state : TransactionState,
) -> Unit raise CliError {
  try @fs.mkdir(state.package_stage) catch {
    err => cli_fail("cannot create \{state.package_stage}: \{err}")
  } noraise {
    _ => ()
  }
  try @fs.mkdir(state.catalog_stage) catch {
    err => cli_fail("cannot create \{state.catalog_stage}: \{err}")
  } noraise {
    _ => ()
  }
  write_new_file(
    path_join(state.package_stage, "generated.mbt"),
    transaction.code,
    0o644,
  )
  write_new_file(
    path_join(state.package_stage, "moon.pkg"),
    transaction.package_manifest,
    0o644,
  )
  let package_files = ["generated.mbt", "moon.pkg"]
  if !transaction.generation_manifest.is_empty() {
    write_new_file(
      path_join(state.package_stage, "generation-manifest.json"),
      transaction.generation_manifest,
      0o644,
    )
    package_files.push("generation-manifest.json")
  }
  write_new_file(
    path_join(state.package_stage, ".lampclaw-i18n.json"),
    ownership_manifest("package", package_files),
    0o644,
  )
  for index = 0; index < transaction.catalog_names.length(); index = index + 1 {
    write_new_file(
      path_join(state.catalog_stage, transaction.catalog_names[index]),
      transaction.catalog_contents[index],
      0o644,
    )
  }
  write_new_file(
    path_join(state.catalog_stage, ".lampclaw-i18n.json"),
    ownership_manifest("catalogs", transaction.catalog_names),
    0o644,
  )
}

///|
async fn commit_transaction(
  state : TransactionState,
  journal : String,
) -> Unit raise CliError {
  try {
    if file_exists(state.package_dir) {
      rename_path(state.package_dir, state.package_backup)
    }
    if file_exists(state.catalog_dir) {
      rename_path(state.catalog_dir, state.catalog_backup)
    }
    rename_path(state.package_stage, state.package_dir)
    rename_path(state.catalog_stage, state.catalog_dir)
    remove_path(state.package_backup)
    remove_path(state.catalog_backup)
    remove_path(journal)
  } catch {
    CommandFailed(message) => {
      let committed = settle_transaction(state, journal) catch {
        CommandFailed(recovery) =>
          cli_fail(
            "i18n transaction failed (\{message}) and recovery failed: \{recovery}",
          )
      }
      if !committed {
        cli_fail("i18n transaction failed and was rolled back: \{message}")
      }
    }
  }
}

///|
async fn open_generation_lock(path : String) -> @fs.File raise CliError {
  if file_exists(path) {
    if !(file_kind(path) is Regular) {
      cli_fail("generation lock is not a regular file: \{path}")
    }
  }
  let file = try
    @fs.open(path, mode=ReadWrite, create_mode=OpenOrCreate, permission=0o600)
  catch {
    err => cli_fail("cannot open generation lock \{path}: \{err}")
  } noraise {
    value => value
  }
  let acquired = try file.try_lock(Exclusive) catch {
    err => {
      file.close()
      cli_fail("cannot acquire generation lock \{path}: \{err}")
    }
  } noraise {
    value => value
  }
  if !acquired {
    file.close()
    cli_fail("another i18n generation transaction is active for: \{path}")
  }
  file
}

///|
async fn generated_file_matches(
  path : String,
  expected : String,
  limit : Int32,
) -> Bool raise CliError {
  if !file_exists(path) || !(file_kind(path) is Regular) {
    return false
  }
  if regular_file_size(path) != @utf8.encode(expected).length().to_int64() {
    return false
  }
  read_file_limited(path, limit) == expected
}

///|
async fn generated_transaction_matches(
  transaction : GeneratedTransaction,
) -> Bool raise CliError {
  if !file_exists(transaction.package_dir) ||
    !file_exists(transaction.catalog_dir) {
    return false
  }
  let package_files = ["generated.mbt", "moon.pkg"]
  if !transaction.generation_manifest.is_empty() {
    package_files.push("generation-manifest.json")
  }
  let expected_package_entries = package_files.copy()
  expected_package_entries.push(".lampclaw-i18n.json")
  if file_exists(path_join(transaction.package_dir, "pkg.generated.mbti")) {
    expected_package_entries.push("pkg.generated.mbti")
  }
  expected_package_entries.sort_by((left, right) => left.lexical_compare(right))
  let actual_package_entries = read_dir(transaction.package_dir)
  actual_package_entries.sort_by((left, right) => left.lexical_compare(right))
  if actual_package_entries != expected_package_entries {
    return false
  }
  if !generated_file_matches(
      path_join(transaction.package_dir, "generated.mbt"),
      transaction.code,
      @generator.I18N_MAX_GENERATED_CODE_BYTES,
    ) ||
    !generated_file_matches(
      path_join(transaction.package_dir, "moon.pkg"),
      transaction.package_manifest,
      64 * 1024,
    ) ||
    !generated_file_matches(
      path_join(transaction.package_dir, ".lampclaw-i18n.json"),
      ownership_manifest("package", package_files),
      64 * 1024,
    ) {
    return false
  }
  if !transaction.generation_manifest.is_empty() &&
    !generated_file_matches(
      path_join(transaction.package_dir, "generation-manifest.json"),
      transaction.generation_manifest,
      1024 * 1024,
    ) {
    return false
  }
  let expected_catalog_entries = transaction.catalog_names.copy()
  expected_catalog_entries.push(".lampclaw-i18n.json")
  expected_catalog_entries.sort_by((left, right) => left.lexical_compare(right))
  let actual_catalog_entries = read_dir(transaction.catalog_dir)
  actual_catalog_entries.sort_by((left, right) => left.lexical_compare(right))
  if actual_catalog_entries != expected_catalog_entries ||
    !generated_file_matches(
      path_join(transaction.catalog_dir, ".lampclaw-i18n.json"),
      ownership_manifest("catalogs", transaction.catalog_names),
      64 * 1024,
    ) {
    return false
  }
  for index = 0; index < transaction.catalog_names.length(); index = index + 1 {
    if !generated_file_matches(
        path_join(transaction.catalog_dir, transaction.catalog_names[index]),
        transaction.catalog_contents[index],
        @runtime.CATALOG_MAX_SOURCE_BYTES,
      ) {
      return false
    }
  }
  true
}

///|
async fn run_locked_transaction(
  transaction : GeneratedTransaction,
) -> Unit raise CliError {
  let journal = transaction_journal(transaction.package_dir)
  recover_transaction(journal, transaction.package_dir, transaction.catalog_dir)
  verify_generated_directory(transaction.package_dir, "package")
  verify_generated_directory(transaction.catalog_dir, "catalogs")
  if generated_transaction_matches(transaction) {
    return
  }
  let state = allocate_transaction_state(transaction)
  stage_transaction(transaction, state) catch {
    CommandFailed(message) => {
      remove_path(state.package_stage) catch {
        _ => ()
      }
      remove_path(state.catalog_stage) catch {
        _ => ()
      }
      cli_fail(message)
    }
  }
  write_new_file(journal, transaction_state_json(state), 0o600) catch {
    CommandFailed(message) => {
      remove_path(state.package_stage) catch {
        _ => ()
      }
      remove_path(state.catalog_stage) catch {
        _ => ()
      }
      cli_fail(message)
    }
  }
  commit_transaction(state, journal)
}

///|
async fn with_generation_locks(
  transaction : GeneratedTransaction,
  first : String,
  second : String,
) -> Unit raise CliError {
  let first_lock = open_generation_lock(first)
  defer first_lock.close()
  defer first_lock.unlock()
  let second_lock = open_generation_lock(second)
  defer second_lock.close()
  defer second_lock.unlock()
  run_locked_transaction(transaction)
}

///|
fn validate_transaction(
  transaction : GeneratedTransaction,
) -> Unit raise CliError {
  if is_root_path(transaction.package_dir) ||
    is_root_path(transaction.catalog_dir) ||
    path_contains(transaction.package_dir, transaction.catalog_dir) ||
    path_contains(transaction.catalog_dir, transaction.package_dir) {
    cli_fail(
      "generated package and catalog directories must be distinct dedicated directories",
    )
  }
  if transaction.catalog_names.length() != transaction.catalog_contents.length() {
    cli_fail("catalog artifact arrays have different lengths")
  }
  if @utf8.encode(transaction.code).length() >
    @generator.I18N_MAX_GENERATED_CODE_BYTES {
    cli_fail("generated MoonBit source exceeds the configured size limit")
  }
  if @utf8.encode(transaction.package_manifest).length() > 64 * 1024 {
    cli_fail("generated package manifest exceeds the configured size limit")
  }
  if @utf8.encode(transaction.generation_manifest).length() > 1024 * 1024 {
    cli_fail("generation manifest exceeds the configured size limit")
  }
  let seen : Map[String, Bool] = Map([])
  for index = 0; index < transaction.catalog_names.length(); index = index + 1 {
    let name = transaction.catalog_names[index]
    if !valid_generated_filename(name) || seen.contains(name) {
      cli_fail("invalid generated catalog filename: \{name}")
    }
    if @utf8.encode(transaction.catalog_contents[index]).length() >
      @runtime.CATALOG_MAX_SOURCE_BYTES {
      cli_fail("generated catalog exceeds the configured size limit: \{name}")
    }
    seen[name] = true
  }
}

///|
async fn write_generated_transaction(
  package_dir : String,
  catalog_dir : String,
  code : String,
  package_manifest : String,
  catalog_names : Array[String],
  catalog_contents : Array[String],
  generation_manifest~ : String = "",
) -> Unit raise CliError {
  let transaction = GeneratedTransaction::{
    package_dir: resolved_path(package_dir),
    catalog_dir: resolved_path(catalog_dir),
    code,
    package_manifest,
    generation_manifest,
    catalog_names,
    catalog_contents,
  }
  validate_transaction(transaction)
  ensure_directory(path_dirname(transaction.package_dir))
  ensure_directory(path_dirname(transaction.catalog_dir))
  let lock_directory = generation_lock_directory()
  ensure_directory(lock_directory)
  let package_lock = transaction_lock_path(
    transaction.package_dir,
    lock_directory,
  )
  let catalog_lock = transaction_lock_path(
    transaction.catalog_dir,
    lock_directory,
  )
  if package_lock.lexical_compare(catalog_lock) <= 0 {
    with_generation_locks(transaction, package_lock, catalog_lock)
  } else {
    with_generation_locks(transaction, catalog_lock, package_lock)
  }
}

///|
fn format_moonbit_source(source : String) -> String {
  @fmt.format(source)
  .split("\n")
  .map(line => line.trim_end().to_owned())
  .collect()
  .join("\n")
  .trim_end()
  .to_owned() +
  "\n"
}

///|
const CLI_VERSION : String = "0.9.3"

///|
fn usage() -> String {
  "moon-i18n \{CLI_VERSION}\n" +
  (
    #|
    #|usage:
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 scaffold  
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 generate [--allow-partial]     
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 check [--allow-partial]     
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 coverage   
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 pseudo --message-profile      
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 export-xliff --message-profile  [--state ]      
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 import-xliff --message-profile  [--state-output ] [--report-output ] [--id-migrations ]      
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 import-i18next --message-profile      
    #|  moonx lampclaw/i18n/cmd/i18n@0.9.3 import-arb --message-profile      
  )
}

///|
fn is_command(arg : String) -> Bool {
  arg == "scaffold" ||
  arg == "generate" ||
  arg == "check" ||
  arg == "coverage" ||
  arg == "pseudo" ||
  arg == "export-xliff" ||
  arg == "import-xliff" ||
  arg == "import-i18next" ||
  arg == "import-arb" ||
  arg == "help" ||
  arg == "--help" ||
  arg == "-h" ||
  arg == "--version" ||
  arg == "-V"
}

///|
fn valid_module_segment(segment : String) -> Bool {
  if segment.is_empty() {
    return false
  }
  let chars = segment.to_array()
  if !((chars[0] >= 'a' && chars[0] <= 'z') ||
    (chars[0] >= 'A' && chars[0] <= 'Z')) {
    return false
  }
  for char in chars {
    if !((char >= 'a' && char <= 'z') ||
      (char >= 'A' && char <= 'Z') ||
      (char >= '0' && char <= '9') ||
      char == '_' ||
      char == '-') {
      return false
    }
  }
  true
}

///|
fn valid_module_name(name : String) -> Bool {
  let segments : Array[String] = name
    .split("/")
    .map(segment => segment.to_owned())
    .collect()
  segments.length() == 2 &&
  valid_module_segment(segments[0]) &&
  valid_module_segment(segments[1])
}

///|
fn scaffold_moon_mod(module_name : String) -> String {
  "name = \"\{module_name}\"\n\n" +
  "version = \"0.9.3\"\n\n" +
  "preferred_target = \"js\"\n\n" +
  "import {\n  \"lampclaw/i18n@\{CLI_VERSION}\",\n}\n"
}

///|
fn scaffold_config() -> String {
  (
    #|{
    #|  "messageProfile": "unicode-mf2-ldml48.2-js-v2",
    #|  "sourceLocale": "en-US",
    #|  "defaultLocale": "en-US",
    #|  "fallbackLocale": "en-US",
    #|  "embeddedLocales": ["en-US"],
    #|  "release": { "minimumCoverage": 1.0 },
    #|  "locales": {
    #|    "en-US": { "direction": "ltr" },
    #|    "zh-CN": { "direction": "ltr" }
    #|  }
    #|}
    #|
  )
}

///|
fn scaffold_schema() -> String {
  (
    #|{
    #|  "messages": { "common": ["hello"] },
    #|  "params": {
    #|    "common.hello": [{ "name": "name", "type": "String" }]
    #|  },
    #|  "descriptions": {
    #|    "common.hello": "Greets a named user."
    #|  }
    #|}
    #|
  )
}

///|
fn scaffold_main_package(module_name : String) -> String {
  "import {\n  \"\{module_name}/i18n\" @app_i18n,\n}\n\n" +
  "supported_targets = \"js\"\n\n" +
  "pkgtype(kind: \"executable\")\n"
}

///|
fn scaffold_main_source() -> String {
  (
    #|///|
    #|fn main {
    #|  let i18n = @app_i18n.I18n::new()
    #|  let translator = i18n.translator(@app_i18n.EnUS)
    #|  println(translator.t(@app_i18n.Common(@app_i18n.Hello("MoonBit"))))
    #|}
    #|
  )
}

///|
fn scaffold_readme(module_name : String) -> String {
  "# \{module_name}\n\n" +
  "Generated by `moon-i18n scaffold`. English is embedded and `zh-CN` " +
  "is emitted as a dynamic catalog.\n\n" +
  "```bash\nmoon update\nmoon check --target js\n" +
  "moon run --target js main\n```\n"
}

///|
async fn write_scaffold_sources(
  root : String,
  module_name : String,
) -> Unit raise CliError {
  write_file(path_join(root, "moon.mod"), scaffold_moon_mod(module_name))
  write_file(path_join(root, "README.md"), scaffold_readme(module_name))
  write_file(path_join(root, "localization/config.json"), scaffold_config())
  write_file(path_join(root, "localization/schema.json"), scaffold_schema())
  write_file(
    path_join(root, "localization/locales/en-US.json"),
    "{\"common\":{\"hello\":\"Hello {$name}\"}}\n",
  )
  write_file(
    path_join(root, "localization/locales/zh-CN.json"),
    "{\"common\":{\"hello\":\"你好,{$name}\"}}\n",
  )
  write_file(
    path_join(root, "main/moon.pkg"),
    scaffold_main_package(module_name),
  )
  write_file(path_join(root, "main/main.mbt"), scaffold_main_source())
}

///|
async fn remove_scaffold_stage_locks(stage : String) -> Unit raise CliError {
  let lock_directory = generation_lock_directory()
  for directory in [path_join(stage, "i18n"), path_join(stage, "public/i18n")] {
    let lock_path = transaction_lock_path(directory, lock_directory)
    if file_exists(lock_path) {
      if !(file_kind(lock_path) is Regular) {
        cli_fail("scaffold generation lock is not a regular file: \{lock_path}")
      }
      remove_path(lock_path)
    }
  }
}

///|
async fn run_scaffold(args : Array[String]) -> Unit raise CliError {
  if args.length() != 3 {
    cli_fail(usage())
  }
  let module_name = args[1]
  if !valid_module_name(module_name) {
    cli_fail("module name must be owner/module with portable ASCII segments")
  }
  let destination = resolved_path(args[2])
  if is_root_path(destination) {
    cli_fail("refusing to scaffold into a filesystem root")
  }
  if file_exists(destination) {
    cli_fail(
      "refusing to overwrite existing scaffold destination: \{destination}",
    )
  }
  let parent = path_dirname(destination)
  ensure_directory(parent)
  let stage = path_join(
    parent,
    ".\{path_basename(destination)}.scaffold-\{@async.now()}",
  )
  if file_exists(stage) {
    cli_fail("cannot allocate scaffold staging directory: \{stage}")
  }
  ensure_directory(stage)
  try {
    write_scaffold_sources(stage, module_name)
    run_generate(
      [
        "generate",
        path_join(stage, "localization/config.json"),
        path_join(stage, "localization/schema.json"),
        path_join(stage, "localization/locales"),
        path_join(stage, "i18n"),
        path_join(stage, "public/i18n"),
      ],
      false,
    )
    remove_scaffold_stage_locks(stage)
    rename_path(stage, destination)
  } catch {
    CommandFailed(message) => {
      remove_path(stage) catch {
        _ => ()
      }
      cli_fail(message)
    }
  }
  println("scaffolded \{module_name} at \{destination}")
}

///|
fn user_args(args : Array[String]) -> Array[String] {
  for i = 0; i < args.length(); i = i + 1 {
    if args[i] == "--" {
      return args[i + 1:].to_owned()
    }
  }
  for i = 0; i < args.length(); i = i + 1 {
    if is_command(args[i]) {
      return args[i:].to_owned()
    }
  }
  []
}

///|
fn without_allow_partial(args : Array[String]) -> Array[String] {
  args.filter(arg => {
    arg != "--allow-partial" &&
    arg != "--diagnostic-format=json" &&
    arg != "--diagnostic-format=human"
  })
}

///|
async fn locale_sources(
  input_dir : String,
) -> Array[@generator.LocaleSource] raise CliError {
  locale_sources_with_limit(input_dir, @generator.I18N_MAX_TOTAL_LOCALE_BYTES)
}

///|
async fn locale_sources_with_limit(
  input_dir : String,
  max_total_bytes : Int32,
) -> Array[@generator.LocaleSource] raise CliError {
  let files = read_dir(input_dir)
  files.sort_by((left, right) => left.lexical_compare(right))
  let sources : Array[@generator.LocaleSource] = []
  let mut total_bytes = 0
  for file in files {
    if file.has_suffix(".json") &&
      file != "config.json" &&
      file != "schema.json" &&
      file != ".lampclaw-i18n.json" {
      if sources.length() >= @generator.I18N_MAX_LOCALES {
        cli_fail(
          "locale directory exceeds the \{@generator.I18N_MAX_LOCALES}-file limit: \{input_dir}",
        )
      }
      let source = read_file_limited(
        path_join(input_dir, file),
        @runtime.CATALOG_MAX_SOURCE_BYTES,
      )
      let source_bytes = @utf8.encode(source).length()
      if source_bytes > max_total_bytes ||
        total_bytes > max_total_bytes - source_bytes {
        cli_fail(
          "locale directory exceeds the \{max_total_bytes}-byte aggregate UTF-8 limit: \{input_dir}",
        )
      }
      total_bytes = total_bytes + source_bytes
      sources.push({
        code: file[:file.length() - ".json".length()].to_owned(),
        source,
      })
    }
  }
  sources
}

///|
fn text_file_content(source : String) -> String {
  if source.has_suffix("\n") {
    source
  } else {
    source + "\n"
  }
}

///|
async fn check_file(
  path : String,
  expected : String,
  kind : String,
) -> Unit raise CliError {
  if !file_exists(path) || read_file(path) != expected {
    cli_fail("i18n \{kind} is out of date: \{path}")
  }
}

///|
async fn check_catalog_set(
  catalog_dir : String,
  expected : Array[String],
) -> Unit raise CliError {
  for file in read_dir(catalog_dir) {
    if file.has_suffix(".json") &&
      file != ".lampclaw-i18n.json" &&
      !expected.contains(file) {
      cli_fail("unexpected i18n catalog: \{path_join(catalog_dir, file)}")
    }
  }
}

///|
async fn check_exact_generated_set(
  directory : String,
  expected : Array[String],
  kind : String,
) -> Unit raise CliError {
  if !file_exists(directory) {
    cli_fail("i18n \{kind} directory is missing: \{directory}")
  }
  let actual = read_dir(directory)
  actual.sort_by((left, right) => left.lexical_compare(right))
  let sorted_expected = expected.copy()
  sorted_expected.sort_by((left, right) => left.lexical_compare(right))
  if actual != sorted_expected {
    cli_fail("i18n \{kind} file set is out of date: \{directory}")
  }
}

///|
async fn load_artifacts(
  config_file : String,
  schema_file : String,
  locale_dir : String,
  enforce_coverage : Bool,
) -> @generator.Artifacts raise CliError {
  let sources = locale_sources(locale_dir)
  if sources.is_empty() {
    cli_fail("no locale JSON files found in: \{locale_dir}")
  }
  let config_source = read_file_limited(
    config_file,
    @runtime.CATALOG_MAX_SOURCE_BYTES,
  )
  let schema_source = read_file_limited(
    schema_file,
    @runtime.CATALOG_MAX_SOURCE_BYTES,
  )
  match
    @generator.generate_with_diagnostics(
      config_source,
      schema_source,
      sources,
      config_path=config_file,
      schema_path=schema_file,
      locale_directory=locale_dir,
      enforce_coverage~,
    ) {
    Ok(value) => value
    Err(diagnostics) => cli_fail(diagnostic_envelope(diagnostics[0]))
  }
}

///|
fn sha256_text(source : String) -> String {
  @crypto.bytes_to_hex_string(@crypto.sha256(@utf8.encode(source)))
}

///|
fn manifest_path(root : String, path : String) -> String {
  let relative = as_path(resolved_path(path)).relative(base=as_path(root))
  let value = relative.to_string().replace_all(old="\\", new="/")
  if value.is_empty() {
    "."
  } else {
    value
  }
}

///|
fn manifest_file(kind : String, path : String, source : String) -> Json {
  Json::object({
    "kind": Json::string(kind),
    "path": Json::string(path),
    "sha256": Json::string(sha256_text(source)),
    "bytes": Json::number(@utf8.encode(source).length().to_double()),
  })
}

///|
async fn generation_manifest(
  config_file : String,
  schema_file : String,
  locale_dir : String,
  package_dir : String,
  catalog_dir : String,
  code : String,
  package_manifest : String,
  catalogs : Array[(String, String)],
  catalog_chunks : Array[@generator.CatalogChunkArtifact],
  deployment_manifest : String,
  contract_hash : String,
  message_profile : String,
) -> String raise CliError {
  let root = path_dirname(resolved_path(config_file))
  let inputs : Array[Json] = [
    manifest_file(
      "config",
      manifest_path(root, config_file),
      read_file_limited(config_file, @runtime.CATALOG_MAX_SOURCE_BYTES),
    ),
    manifest_file(
      "schema",
      manifest_path(root, schema_file),
      read_file_limited(schema_file, @runtime.CATALOG_MAX_SOURCE_BYTES),
    ),
  ]
  for catalog in catalogs {
    let locale_file = path_join(locale_dir, catalog.0 + ".json")
    inputs.push(
      manifest_file(
        "locale",
        manifest_path(root, locale_file),
        read_file_limited(locale_file, @runtime.CATALOG_MAX_SOURCE_BYTES),
      ),
    )
  }
  let outputs : Array[Json] = [
    manifest_file(
      "moonbit",
      manifest_path(root, path_join(package_dir, "generated.mbt")),
      code,
    ),
    manifest_file(
      "moon-package",
      manifest_path(root, path_join(package_dir, "moon.pkg")),
      package_manifest,
    ),
  ]
  outputs.push(
    manifest_file(
      "deployment-manifest",
      manifest_path(root, path_join(catalog_dir, "manifest.json")),
      deployment_manifest,
    ),
  )
  for catalog in catalog_chunks {
    outputs.push(
      manifest_file(
        "catalog-chunk",
        manifest_path(root, path_join(catalog_dir, catalog.path)),
        catalog.source,
      ),
    )
  }
  Json::object({
    "manifestVersion": Json::number(1.0),
    "generator": Json::string("lampclaw/i18n"),
    "generatorVersion": Json::string(CLI_VERSION),
    "profile": Json::string(message_profile),
    "contractHash": Json::string(contract_hash),
    "inputs": Json::array(inputs),
    "outputs": Json::array(outputs),
  }).stringify(indent=2) +
  "\n"
}

///|
async fn run_generate(
  args : Array[String],
  check_mode : Bool,
  diagnostic_json~ : Bool = false,
) -> Unit raise CliError {
  let allow_partial = args.contains("--allow-partial")
  let values = without_allow_partial(args)
  if values.length() != 6 {
    cli_fail(usage())
  }
  let artifacts = load_artifacts(
    values[1],
    values[2],
    values[3],
    !allow_partial,
  )
  let code = format_moonbit_source(artifacts.code)
  let manifest = text_file_content(artifacts.package_manifest)
  let package_dir = values[4]
  let generated_manifest = generation_manifest(
    values[1],
    values[2],
    values[3],
    package_dir,
    values[5],
    code,
    manifest,
    artifacts.catalogs,
    artifacts.catalog_chunks,
    artifacts.deployment_manifest,
    artifacts.contract_hash,
    artifacts.message_profile,
  )
  if check_mode {
    check_file(
      path_join(package_dir, "generated.mbt"),
      code,
      "generated bindings",
    )
    check_file(
      path_join(package_dir, "moon.pkg"),
      manifest,
      "generated package manifest",
    )
    let package_files = [
      "generated.mbt", "moon.pkg", "generation-manifest.json",
    ]
    check_file(
      path_join(package_dir, ".lampclaw-i18n.json"),
      ownership_manifest("package", package_files),
      "package ownership manifest",
    )
    check_file(
      path_join(package_dir, "generation-manifest.json"),
      generated_manifest,
      "generation manifest",
    )
    let expected_package_files = [
      ".lampclaw-i18n.json", "generated.mbt", "generation-manifest.json", "moon.pkg",
    ]
    if file_exists(path_join(package_dir, "pkg.generated.mbti")) {
      expected_package_files.push("pkg.generated.mbti")
    }
    check_exact_generated_set(
      package_dir, expected_package_files, "generated package",
    )
    check_file(
      path_join(values[5], "manifest.json"),
      artifacts.deployment_manifest,
      "deployment manifest",
    )
    for catalog in artifacts.catalog_chunks {
      check_file(
        path_join(values[5], catalog.path),
        catalog.source,
        "catalog chunk",
      )
    }
    let catalog_files : Array[String] = ["manifest.json"]
    for catalog in artifacts.catalog_chunks {
      catalog_files.push(catalog.path)
    }
    check_catalog_set(values[5], catalog_files)
    check_file(
      path_join(values[5], ".lampclaw-i18n.json"),
      ownership_manifest("catalogs", catalog_files),
      "catalog ownership manifest",
    )
    let expected_catalog_files = catalog_files.copy()
    expected_catalog_files.push(".lampclaw-i18n.json")
    check_exact_generated_set(values[5], expected_catalog_files, "catalog")
  } else {
    let catalog_names : Array[String] = ["manifest.json"]
    let catalog_contents : Array[String] = [artifacts.deployment_manifest]
    for catalog in artifacts.catalog_chunks {
      catalog_names.push(catalog.path)
      catalog_contents.push(catalog.source)
    }
    write_generated_transaction(
      package_dir,
      values[5],
      code,
      manifest,
      catalog_names,
      catalog_contents,
      generation_manifest=generated_manifest,
    )
  }
  write_artifact_diagnostics(artifacts.diagnostics, diagnostic_json)
  println(artifacts.coverage_report)
}

///|
async fn run_coverage(
  args : Array[String],
  diagnostic_json~ : Bool = false,
) -> Unit raise CliError {
  if args.length() != 4 {
    cli_fail(usage())
  }
  let artifacts = load_artifacts(args[1], args[2], args[3], false)
  write_artifact_diagnostics(artifacts.diagnostics, diagnostic_json)
  println(artifacts.coverage_report)
}

///|
async fn run_command(
  args : Array[String],
  diagnostic_json~ : Bool = false,
) -> Unit raise CliError {
  if args.is_empty() {
    cli_fail(usage())
  }
  match args[0] {
    "--help" | "-h" | "help" => println(usage())
    "--version" | "-V" => println("moon-i18n \{CLI_VERSION}")
    "scaffold" => run_scaffold(args)
    "generate" => run_generate(args, false, diagnostic_json~)
    "check" => run_generate(args, true, diagnostic_json~)
    "coverage" => run_coverage(args, diagnostic_json~)
    "pseudo" => run_pseudo(args)
    "export-xliff" => run_export_xliff(args)
    "import-xliff" => run_import_xliff(args)
    "import-i18next" => run_import_i18next(args)
    "import-arb" => run_import_arb(args)
    _ => cli_fail(usage())
  }
}

///|
async fn write_artifact_diagnostics(
  diagnostics : Array[@generator.Diagnostic],
  json : Bool,
) -> Unit raise CliError {
  for diagnostic in diagnostics {
    let rendered = if json {
      diagnostic.to_json_string()
    } else {
      diagnostic.to_human_string()
    }
    try @stdio.stderr.write(rendered + "\n") catch {
      error => cli_fail("cannot write i18n diagnostic: \{error}")
    } noraise {
      _ => ()
    }
  }
}

///|
fn diagnostic_json_enabled(args : Array[String]) -> Bool {
  args.contains("--diagnostic-format=json")
}

///|
fn without_diagnostic_format(args : Array[String]) -> Array[String] {
  args.filter(arg => {
    arg != "--diagnostic-format=json" && arg != "--diagnostic-format=human"
  })
}

///|
fn cli_diagnostic(
  message : String,
  args : Array[String],
) -> @generator.Diagnostic {
  let values = without_diagnostic_format(args)
  let path = if values.length() > 1 { values[1] } else { "" }
  {
    code: "I18N0001",
    severity: Error,
    message,
    path,
    span: {
      start: { byte_offset: 0, line: 1, column: 1, },
      end: { byte_offset: 0, line: 1, column: 1, },
    },
  }
}

///|
fn render_cli_error(message : String, args : Array[String]) -> String {
  let json = diagnostic_json_enabled(args)
  if message.has_prefix(DIAGNOSTIC_ENVELOPE) {
    let body = message[DIAGNOSTIC_ENVELOPE.length():].to_owned()
    let pieces : Array[String] = body
      .split(DIAGNOSTIC_HUMAN_SEPARATOR)
      .map(piece => piece.to_owned())
      .collect()
    if pieces.length() == 2 {
      return if json { pieces[0] } else { pieces[1] }
    }
  }
  let diagnostic = cli_diagnostic(message, args)
  if json {
    diagnostic.to_json_string()
  } else {
    diagnostic.to_human_string()
  }
}

///|
fn is_generated_content(source : String) -> Bool {
  source.has_prefix(
    "///|\n/// Generated by lampclaw/i18n. Do not edit by hand.",
  ) ||
  source.has_prefix("/// Generated by lampclaw/i18n. Do not edit by hand.") ||
  source.has_prefix("// Generated by lampclaw/i18n. Do not edit by hand.")
}

///|
async fn main {
  let args = user_args(@env.args())
  let json = diagnostic_json_enabled(args)
  run_command(without_diagnostic_format(args), diagnostic_json=json) catch {
    CommandFailed(message) => die(render_cli_error(message, args))
  }
}