///|
// Image targets as asciidoctor-pdf resolves them (its `Asciidoctor::Image`
// extension and `resolve_image_path`): a data URI carries the image
// itself, anything else is a path whose extension (or `format`) names the
// format.

///|
/// An image target: a path, or the bytes of a data URI.
priv enum ImageTarget {
  Path(String)
  Data(Bytes)
}

///|
/// `Asciidoctor::Image.target_and_format`: a data URI
/// (`data:image/;base64,`, `jpg` read as `jpeg` and `svg+xml` as
/// `svg`) decoded, else the target and the `format` attribute or its
/// lowercased extension ("" when it has none).
fn image_target_and_format(
  target : String,
  format : String?,
) -> (ImageTarget, String) {
  if target.has_prefix("data:image/") {
    let rest = target["data:image/".length():].to_owned()
    match rest.find(";base64,") {
      Some(i) => {
        let fmt = rest[:i].to_owned()
        if fmt
          is ("png"
          | "jpg"
          | "jpeg"
          | "gif"
          | "pdf"
          | "bmp"
          | "tiff"
          | "svg+xml") {
          let fmt = match fmt {
            "jpg" => "jpeg"
            "svg+xml" => "svg"
            f => f
          }
          return (Data(@svg.decode_base64(rest[i + 8:])), fmt)
        }
      }
      None => ()
    }
  }
  let format = match format {
    Some(f) => f
    None => {
      let ext = @core.extname(target, fallback="")
      if ext.length() > 1 {
        ext[1:].to_owned().to_lower()
      } else {
        ""
      }
    }
  }
  (Path(target), format)
}

///|
/// The bytes of an image target; a path is resolved against `start` (the
/// images directory) in the document's jail. Also the path, for messages
/// (the target itself for a data URI).
fn load_image_target(
  node : @core.Node,
  target : ImageTarget,
  start? : String,
) -> (Bytes?, String) {
  match target {
    Data(bytes) => (Some(bytes), "")
    Path(p) => {
      let path = node.normalize_system_path(p, start?)
      (node.vfs().read(path), path)
    }
  }
}