///|
fn workflow() -> Json raise @restrict.RestrictError {
  let samples = @restrict.read_fasta(
    ">sample-a synthetic\nACGTAAACGT\n>sample-b synthetic\nACGTCCCCCC\n>sample-c synthetic\nCCCCCCCCCC\n",
    topology=Circular,
  )
  let enzymes = @restrict.read_enzymes(
    "name\tmotif\ttop\tbottom\nmodel-ac\tACGT\t2\t2\nmodel-cc\tCC\t1\t1\n",
  )
  let maps : Array[@restrict.Digest] = []
  let fingerprints : Array[Array[String]] = []
  for sample in samples {
    let report = @restrict.digest(sample.dna, enzymes[0])
    @restrict.verify_digest(sample.dna, [enzymes[0]], report)
    let decoded = @restrict.read_report(@restrict.write_report(report))
    @restrict.verify_digest(sample.dna, [enzymes[0]], decoded)
    maps.push(report)
    let row : Array[String] = []
    for enzyme in enzymes {
      row.push(
        @restrict.band_signature(@restrict.digest(sample.dna, enzyme).fragments),
      )
    }
    fingerprints.push(row)
  }
  let pieces = @restrict.annotate_fragments(
    samples[0].dna,
    [enzymes[0]],
    maps[0],
    [{ id: "origin-window", start: 8, length: 4 }],
  )
  let partial = @restrict.partial_digests(
    samples[0].dna,
    [enzymes[0]],
    max_scenarios=4,
  )
  let comparison = @restrict.compare_maps(
    samples[0].dna,
    [enzymes[0]],
    maps[0],
    samples[1].dna,
    [enzymes[0]],
    maps[1],
  )
  let panel = @restrict.select_panel(fingerprints, 2)
  let sticky_dna = @restrict.Dna::new("GTAC", topology=Circular)
  let sticky = @restrict.digest(
    sticky_dna,
    @restrict.Enzyme::new("sticky-demo", "ACGT", 1, 3),
  )
  let (before, after) = @restrict.cut_ends(sticky_dna, sticky.cuts[0])
  {
    "sample_ids": samples.map(s => s.id).to_json(),
    "first_map": maps[0].to_json(),
    "annotation_pieces": pieces.to_json(),
    "partial": partial.to_json(),
    "comparison": comparison.to_json(),
    "fingerprints": fingerprints.to_json(),
    "panel": panel.to_json(),
    "sticky_join": @restrict.compatible_ends(before, after).to_json(),
  }
}

///|
fn main {
  println(workflow().stringify()) catch {
    _ => @abort.abort("synthetic workflow failed")
  }
}