use clap::Clap;
use std::fs::File;
use std::io::{stdin, BufRead, BufReader};

mod lol;

///this is a test.
#[derive(Clap)]
#[clap(author, about, version)]
#[clap(
    after_help = "Examples:\n\tlolcatrs f - g\tOutput f's contents, then stdin, then g's contents.\n\tfortune | lolcat\tDisplay a rainbow cookie."
)]
struct CmdOpts {
    #[clap(short = 'p', long, default_value = "1.0")]
    /// Rainbow spread
    spread: f64,

    /// Rainbow frequency
    #[clap(short = 'F', long, default_value = "0.1")]
    freq: f64,

    /// Rainbow seed, 0 = random
    #[clap(short = 'S', long, default_value = "0.0")]
    seed: f64,

    /// Invert fg and bg
    #[clap(short = 'i', long)]
    invert: bool,

    /// Files to concatenate(`-` for STDIN)
    files: Vec<String>,
}

fn read_line() -> Option<(String, usize)> {
    let mut input = String::new();
    match stdin().read_line(&mut input) {
        Ok(n) => Some((input, n)),
        _ => None,
    }
}

fn main() {
    let opts: CmdOpts = CmdOpts::parse();

    let mut files = opts.files;
    if files.is_empty() {
        files.push("-".to_string());
    }

    let mut seed: f64 = opts.seed;
    if seed == 0.0 {
        seed = rand::random::<f64>() * 1_000_000.0;
    }

    for file_path in files {
        if file_path == "-" {
            while let Some((x, n)) = read_line() {
                lol::print_rainbow(&x, opts.freq, seed, opts.spread, opts.invert);
                if n == 0 {
                    // EOF
                    break;
                }
                seed += 1.0;
            }
        } else {
            let file = match File::open(&file_path) {
                Ok(x) => x,
                Err(e) => {
                    eprintln!("Could not open {}: {}.", file_path, e);
                    continue;
                }
            };
            let buf = BufReader::new(file);
            for x in buf.lines() {
                match x {
                    Ok(x) => {
                        lol::print_rainbow(&x, opts.freq, seed, opts.spread, opts.invert);
                        println!();
                        seed += 1.0;
                    }
                    Err(e) => {
                        eprintln!("Error while reading {}: {}.", file_path, e);
                        continue;
                    }
                }
            }
        }
    }
}