// Container logs management
//
// NOTE (2026-02-08): Error handling in this file has been simplified to work around
// a MoonBit compiler C code generation issue when combining async functions with
// complex catch blocks and closures. This affects native backend only.

///|
/// Build docker logs command arguments from LogOptions
fn build_logs_args(
  container_id : String,
  options : LogOptions,
) -> Array[String] {
  let args : Array[String] = ["logs"]

  // Add follow option
  if options.follow {
    args.push("-f")
  }

  // Add timestamps option
  if options.timestamps {
    args.push("-t")
  }

  // Add tail option
  match options.tail {
    Some(n) => {
      args.push("--tail")
      args.push(n.to_string())
    }
    None => ()
  }

  // Add since option
  match options.since {
    Some(timestamp) => {
      args.push("--since")
      args.push(timestamp)
    }
    None => ()
  }

  // Add until option
  match options.until {
    Some(timestamp) => {
      args.push("--until")
      args.push(timestamp)
    }
    None => ()
  }

  // Add container ID
  args.push(container_id)
  args
}

///|
/// Get all logs from the container
pub async fn Container::get_logs(
  self : Container,
) -> Result[String, TestContainerError] noraise {
  let args = ["logs", self.id]
  exec_docker(args)
}

///|
/// Get logs with specified options
pub async fn Container::get_logs_with_options(
  self : Container,
  options : LogOptions,
) -> Result[String, TestContainerError] {
  // Check if follow option is set
  if options.follow {
    return Err(
      InvalidConfiguration(
        "Cannot use follow option with get_logs_with_options. Use stream_logs instead.",
      ),
    )
  }
  let args = build_logs_args(self.id, options)
  exec_docker(args)
}

///|
/// Stream logs line by line with a callback
/// Note: This implementation collects all output first, then processes it line by line.
/// It does not support true streaming for follow=true mode.
pub async fn Container::stream_logs(
  self : Container,
  callback : (String) -> Unit,
  options? : LogOptions,
) -> Result[Unit, TestContainerError] {
  // Get options or use default
  let options = match options {
    Some(opts) => opts
    None => LogOptions::default()
  }

  // For follow mode, we need to disable it since we collect output first
  // True streaming would require more complex implementation
  let stream_options = { ..options, follow: false }
  let args = build_logs_args(self.id, stream_options)

  // Run docker logs using exec_docker (works on both native and JS backends)
  // NOTE: Simplified to avoid C code generation issue with nested match/catch
  let output_result = exec_docker(args)

  // Early return on error
  let output_text = match output_result {
    Err(e) => return Err(e)
    Ok(text) => text
  }

  // Process output line by line
  let lines = output_text.split("\n").to_array()
  for i = 0; i < lines.length(); i = i + 1 {
    let line = lines[i]
    // Convert StringView to String and call callback
    let line_str = "\{line}"
    if line_str.length() > 0 {
      callback(line_str)
    }
  }
  Ok(())
}