use clap::Parser;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::io::prelude::*;
use std::path::Path;
use cubiculum::extract::extract::{bed_to_fraction, BedFractionMode};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(long, short = 'i', default_value_t = String::from("stdin"))]
input: String,
#[arg(long, short = 'o', default_value_t = String::from("stdout"))]
output: String,
#[arg(long, short='m', default_value_t = String::from("all"))]
mode: String,
#[arg(long, short='n', action)]
intron: bool,
#[arg(long, short='b', action)]
bed6: bool
}
fn main() {
let args = Args::parse();
match args.mode.as_str() {
"all" => { BedFractionMode::All },
"cds" => { BedFractionMode::Cds },
"utr" => { BedFractionMode::Utr },
"5utr" => { BedFractionMode::Utr5 },
"3utr" => { BedFractionMode::Utr3 },
_ => {
panic!("Invalid 'mode' has been provided: {}. Valid modes are: all, cds, utr, 3utr, 5utr", args.mode)
}
};
let input_file = match args.input.as_str() {
"stdin" => {Box::new(io::stdin().lock()) as Box<dyn BufRead>},
_ => {
let path = File::open(args.input).unwrap();
Box::new(BufReader::new(path)) as Box<dyn BufRead>
}
};
let mut output_file = match args.output.as_str() {
"stdout" => {Box::new(io::stdout()) as Box<dyn Write>},
_ => {
let path = Path::new(&args.output);
Box::new(File::create(&path).unwrap()) as Box<dyn Write>
}
};
for line_ in input_file.lines() {
if let Ok(line) = line_ {
let result: Option<String> = bed_to_fraction(line, &args.mode, args.intron, args.bed6);
if let Some(fraction) = result {
if let Err(e) = writeln!(output_file, "{}", fraction) {
eprintln!("Failed to write the line: {}", e);
}
}
}
}
}