///|
fn usage() -> String {
  (
    #|gffkit  
    #|
    #|Commands:
    #|  validate       Parse the file and report feature count
    #|  stats          Print feature, gene, transcript, exon, and CDS counts
    #|  filter   Print BED lines for features of a type
    #|  to-json        Export parsed annotation as JSON
    #|  to-bed         Export parsed annotation as BED6
    #|
  )
}

///|
fn read_annotation(path : String) -> @lib.Annotation raise {
  @lib.parse_auto(@fs.read_file_to_string(path))
}

///|
fn print_stats(annotation : @lib.Annotation) -> Unit {
  let summary = annotation.summary()
  println("features\t\{summary.feature_count}")
  println("genes\t\{summary.gene_count}")
  println("transcripts\t\{summary.transcript_count}")
  println("exons\t\{summary.exon_count}")
  println("cds\t\{summary.cds_count}")
}

///|
fn print_filtered(annotation : @lib.Annotation, feature_type : String) -> Unit {
  for feature in annotation.filter_by_type(feature_type) {
    println(feature.to_bed_line())
  }
}

///|
fn run(args : Array[String]) -> Unit raise {
  let offset = if args.length() > 0 && args[0].contains("gffkit") {
    1
  } else {
    0
  }
  guard args.length() >= offset + 2 else {
    println(usage())
    @sys.exit(2)
  }
  let command = args[offset]
  match command {
    "validate" => {
      let annotation = read_annotation(args[offset + 1])
      println("valid\t\{annotation.features.length()}")
    }
    "stats" => print_stats(read_annotation(args[offset + 1]))
    "filter" => {
      guard args.length() >= offset + 3 else {
        println(usage())
        @sys.exit(2)
      }
      print_filtered(read_annotation(args[offset + 2]), args[offset + 1])
    }
    "to-json" => println(read_annotation(args[offset + 1]).to_json())
    "to-bed" => println(read_annotation(args[offset + 1]).to_bed())
    _ => {
      println(usage())
      @sys.exit(2)
    }
  }
}

///|
fn main {
  try run(@env.args()) catch {
    err => {
      println("error: \{err}")
      @sys.exit(1)
    }
  } noraise {
    _ => ()
  }
}