///|
fn format_optional(value : Double?) -> String {
  match value {
    Some(v) => v.to_string()
    None => "None"
  }
}

///|
fn main {
  println("=== rtracklayer BigWig Demo ===")
  let targets = [
    @src.BigBedTarget::create("chr1", 1000) catch {
      _ => abort("failed to create chr1")
    },
    @src.BigBedTarget::create("chr2", 500) catch {
      _ => abort("failed to create chr2")
    },
  ]
  let intervals = [
    @src.BigWigInterval::create("chr1", 0, 10, 1.0),
    @src.BigWigInterval::create("chr1", 10, 20, 2.5),
    @src.BigWigInterval::create("chr1", 20, 30, -3.0),
    @src.BigWigInterval::create("chr2", 0, 100, 7.5),
  ]

  println("\n1. Write a compressed BigWig v4 stream (zlib blocks)")
  let config = @src.BigWigWriteConfig::create(block_size=64, compress=true) catch {
    _ => abort("failed to create BigWig configuration")
  }
  let bytes = @src.bigwig_write(targets, intervals, config~) catch {
    _ => abort("failed to write BigWig")
  }
  let file = @src.bigwig_parse(bytes) catch {
    _ => abort("failed to parse BigWig")
  }
  println("   bytes=" + bytes.length().to_string())
  let header = file.header()
  println(
    "   version=\{header.version}, zoom levels=\{file.zoom_levels().length()}, sections=\{file.section_count()}, little endian=\{header.little_endian}",
  )
  let summary = file.total_summary()
  println(
    "   summary: bases=\{summary.valid_count}, min=\{summary.min_val}, max=\{summary.max_val}, sum=\{summary.sum_data}",
  )

  println("\n2. Query overlapping intervals (whole entries, unclipped)")
  let hits = file.intervals("chr1", start=5, end_=Some(25)) catch {
    _ => abort("failed to query intervals")
  }
  for hit in hits {
    println(
      "   " +
      hit.chrom +
      ":" +
      hit.start.to_string() +
      "-" +
      hit.end.to_string() +
      " value=" +
      hit.value.to_string(),
    )
  }

  println("\n3. Per-base values with NaN filling the gaps")
  let values = file.values("chr1", start=0, end_=Some(40)) catch {
    _ => abort("failed to query values")
  }
  let cells : Array[String] = []
  for i in 0.. abort("failed to compute means")
  }
  for i in 0.. abort("failed to compute " + name)
    }
    println("   " + name + " = " + format_optional(values_one[0]))
  }

  println("\n6. Writer rejects overlapping intervals")
  let bad = [
    @src.BigWigInterval::create("chr1", 0, 20, 1.0),
    @src.BigWigInterval::create("chr1", 10, 30, 2.0),
  ]
  try {
    ignore(@src.bigwig_write(targets, bad))
    abort("overlapping input unexpectedly accepted")
  } catch {
    @src.BigWigError(message) => println("   rejected: " + message)
  }

  println("\n7. Reader rejects a damaged BigWig header")
  let damaged = bytes.copy()
  damaged[0] = 0
  try {
    ignore(@src.bigwig_parse(damaged))
    abort("damaged BigWig unexpectedly parsed")
  } catch {
    @src.BigWigError(message) => println("   rejected: " + message)
  }

  println("\n=== Demo Complete ===")
}