///|
fn run(args : Array[String]) -> Int32 {
  if args.length() != 2 {
    eprintln("usage: moon run src/cmd/write_demo -- ")
    return 2
  }
  let writer = @lib.Hdf5Writer::new()
  writer.set_attribute_sharing(true)
  writer.set_fill_sharing(true)
  writer.set_filter_sharing(true)
  try {
    writer.add_group("/experiment")
    writer.add_dataset(
      "/experiment/counts",
      [2UL, 3UL],
      Int64Values([1L, 2L, 3L, 4L, 5L, 6L]),
    )
    writer.add_dataset(
      "/experiment/reference_target",
      [2UL],
      Int64Values([11L, 12L]),
    )
    writer.add_dataset(
      "/experiment/region_target",
      [6UL],
      Int64Values([10L, 11L, 12L, 13L, 14L, 15L]),
    )
    let region_ref = @lib.Datatype::write_region_reference()
    writer.add_dataset(
      "/experiment/region_references",
      [7UL],
      StructuredValues(region_ref, [
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionPoints([[4UL], [0UL], [3UL]]),
        ),
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionHyperslab([1UL], [1UL], [1UL], [2UL]),
        ),
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionHyperslab([0UL], [3UL], [2UL], [2UL]),
        ),
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionBlocks([
            { start: [0UL], end: [1UL], },
            { start: [4UL], end: [4UL], },
          ]),
        ),
        @lib.RegionReference(Some("/experiment/region_target"), @lib.RegionAll),
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionEmpty,
        ),
        @lib.RegionReference(None, @lib.RegionEmpty),
      ]),
    )
    writer.add_attribute(
      "/experiment/region_target",
      "window",
      [],
      StructuredValues(region_ref, [
        @lib.RegionReference(
          Some("/experiment/region_target"),
          @lib.RegionHyperslab([2UL], [1UL], [1UL], [3UL]),
        ),
      ]),
    )
    writer.add_dataset(
      "/experiment/references",
      [4UL],
      ObjectReferenceValues([
        Some("/experiment/reference_target"),
        Some("/experiment"),
        None,
        Some("/"),
      ]),
    )
    writer.add_attribute(
      "/experiment/reference_target",
      "self_ref",
      [],
      ObjectReferenceValues([Some("/experiment/reference_target")]),
    )
    writer.add_soft_link("/experiment", "latest", "/experiment/counts")
    writer.add_external_link(
      "/experiment", "external", "external-target.h5", "/experiment/counts",
    )
    writer.add_external_dataset(
      "/experiment/external_raw",
      [6UL],
      Int32Values([10, 20, 30, 40, 50, 60]),
      [
        {
          file_name: "moon-hdf5-demo-external-0.bin",
          file_offset: 4UL,
          data_size: 8UL,
        },
        {
          file_name: "moon-hdf5-demo-external-1.bin",
          file_offset: 0UL,
          data_size: 16UL,
        },
      ],
    )
    writer.add_dataset(
      "/experiment/labels",
      [2UL],
      FixedStringValues(["control", "sample"], 8),
    )
    writer.add_dataset(
      "/experiment/metrics",
      [2UL],
      Float64Values([1.5, -2.25]),
    )
    let sparse = Array::make(35, -7L)
    sparse[0] = 42L
    sparse[17] = 99L
    sparse[34] = -2L
    writer.add_chunked_dataset(
      "/experiment/chunked",
      [5UL, 7UL],
      [2U, 3U],
      Int64Values(sparse),
      fill_value=Int64Values([-7L]),
      filters=[Shuffle, Deflate(6), Fletcher32],
    )
    writer.add_extensible_dataset(
      "/experiment/series",
      [0UL, 2UL],
      [None, Some(2UL)],
      [2U, 2U],
      Int64Values([]),
      fill_value=Int64Values([-1L]),
      filters=[Shuffle, Deflate(6), Fletcher32],
    )
    writer.append_dataset(
      "/experiment/series",
      [2UL, 2UL],
      Int64Values([10L, 11L, 20L, 21L]),
    )
    writer.append_dataset(
      "/experiment/series",
      [1UL, 2UL],
      Int64Values([30L, 31L]),
    )
    writer.resize_dataset("/experiment/series", [4UL, 2UL])
    writer.add_extensible_dataset(
      "/experiment/multi_growth",
      [2UL, 2UL],
      [None, None],
      [1U, 2U],
      Int64Values([1L, 2L, 3L, 4L]),
      fill_value=Int64Values([-1L]),
    )
    writer.resize_dataset("/experiment/multi_growth", [3UL, 3UL])
    writer.add_extensible_dataset(
      "/experiment/multi_append",
      [2UL, 2UL],
      [None, None],
      [1U, 2U],
      Int64Values([1L, 2L, 3L, 4L]),
      fill_value=Int64Values([-1L]),
    )
    writer.append_dataset(
      "/experiment/multi_append",
      [1UL, 1UL],
      Int64Values([5L]),
    )
    writer.add_extensible_dataset(
      "/experiment/multi_filtered",
      [2UL, 2UL],
      [None, None],
      [1U, 2U],
      Int64Values([11L, 12L, 21L, 22L]),
      fill_value=Int64Values([0L]),
      filters=[Shuffle, Deflate(6), Fletcher32],
    )
    writer.resize_dataset("/experiment/multi_filtered", [4UL, 3UL])
    let deep = Array::make(256, 0L)
    for index in 0.. {
      eprintln("write error: " + error.to_string())
      1
    }
  }
}

///|
fn main {
  @sys.exit(run(@env.args()))
}