use itertools::Itertools;
use plotters::data::fitting_range;
use plotters::prelude::*;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::{self, prelude::*, BufReader};

fn read_data<BR: BufRead>(reader: BR) -> HashMap<(String, String), Vec<f64>> {
    let mut ds = HashMap::new();
    for l in reader.lines() {
        let line = l.unwrap();
        let tuple: Vec<&str> = line.split('\t').collect();
        if tuple.len() == 3 {
            let key = (String::from(tuple[0]), String::from(tuple[1]));
            let entry = ds.entry(key).or_insert_with(Vec::new);
            entry.push(tuple[2].parse::<f64>().unwrap());
        }
    }
    ds
}

const OUT_FILE_NAME: &'static str = "plotters-doc-data/boxplot.svg";
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let root = SVGBackend::new(OUT_FILE_NAME, (1024, 768)).into_drawing_area();
    root.fill(&WHITE)?;

    let root = root.margin(5, 5, 5, 5);

    let (upper, lower) = root.split_vertically(512);

    let args: Vec<String> = env::args().collect();

    let ds = if args.len() < 2 {
        read_data(io::Cursor::new(get_data()))
    } else {
        let file = fs::File::open(&args[1])?;
        read_data(BufReader::new(file))
    };
    let dataset: Vec<(String, String, Quartiles)> = ds
        .iter()
        .map(|(k, v)| (k.0.clone(), k.1.clone(), Quartiles::new(&v)))
        .collect();

    let host_list: Vec<_> = dataset
        .iter()
        .unique_by(|x| x.0.clone())
        .sorted_by(|a, b| b.2.median().partial_cmp(&a.2.median()).unwrap())
        .map(|x| x.0.clone())
        .collect();

    let mut colors = (0..).map(Palette99::pick);
    let mut offsets = (-12..).step_by(24);
    let mut series = BTreeMap::new();
    for x in dataset.iter() {
        let entry = series
            .entry(x.1.clone())
            .or_insert_with(|| (Vec::new(), colors.next().unwrap(), offsets.next().unwrap()));
        entry.0.push((x.0.clone(), &x.2));
    }

    let values: Vec<f32> = dataset
        .iter()
        .map(|x| x.2.values().to_vec())
        .flatten()
        .collect();
    let values_range = fitting_range(values.iter());

    let mut chart = ChartBuilder::on(&upper)
        .x_label_area_size(40)
        .y_label_area_size(80)
        .caption("Ping Boxplot", ("sans-serif", 20))
        .build_cartesian_2d(
            values_range.start - 1.0..values_range.end + 1.0,
            host_list[..].into_segmented(),
        )?;

    chart
        .configure_mesh()
        .x_desc("Ping, ms")
        .y_desc("Host")
        .y_labels(host_list.len())
        .light_line_style(&WHITE)
        .draw()?;

    for (label, (values, style, offset)) in &series {
        chart
            .draw_series(values.iter().map(|x| {
                Boxplot::new_horizontal(SegmentValue::CenterOf(&x.0), &x.1)
                    .width(20)
                    .whisker_width(0.5)
                    .style(style)
                    .offset(*offset)
            }))?
            .label(label)
            .legend(move |(x, y)| Rectangle::new([(x, y - 6), (x + 12, y + 6)], style.filled()));
    }
    chart
        .configure_series_labels()
        .position(SeriesLabelPosition::UpperRight)
        .background_style(WHITE.filled())
        .border_style(&BLACK.mix(0.5))
        .legend_area_size(22)
        .draw()?;

    let drawing_areas = lower.split_evenly((1, 2));
    let (left, right) = (&drawing_areas[0], &drawing_areas[1]);

    let quartiles_a = Quartiles::new(&[
        6.0, 7.0, 15.9, 36.9, 39.0, 40.0, 41.0, 42.0, 43.0, 47.0, 49.0,
    ]);
    let quartiles_b = Quartiles::new(&[16.0, 17.0, 50.0, 60.0, 40.2, 41.3, 42.7, 43.3, 47.0]);

    let ab_axis = ["a", "b"];

    let values_range = fitting_range(
        quartiles_a
            .values()
            .iter()
            .chain(quartiles_b.values().iter()),
    );
    let mut chart = ChartBuilder::on(&left)
        .x_label_area_size(40)
        .y_label_area_size(40)
        .caption("Vertical Boxplot", ("sans-serif", 20))
        .build_cartesian_2d(
            ab_axis[..].into_segmented(),
            values_range.start - 10.0..values_range.end + 10.0,
        )?;

    chart.configure_mesh().light_line_style(&WHITE).draw()?;
    chart.draw_series(vec![
        Boxplot::new_vertical(SegmentValue::CenterOf(&"a"), &quartiles_a),
        Boxplot::new_vertical(SegmentValue::CenterOf(&"b"), &quartiles_b),
    ])?;

    let mut chart = ChartBuilder::on(&right)
        .x_label_area_size(40)
        .y_label_area_size(40)
        .caption("Horizontal Boxplot", ("sans-serif", 20))
        .build_cartesian_2d(-30f32..90f32, 0..3)?;

    chart.configure_mesh().light_line_style(&WHITE).draw()?;
    chart.draw_series(vec![
        Boxplot::new_horizontal(1, &quartiles_a),
        Boxplot::new_horizontal(2, &Quartiles::new(&[30])),
    ])?;

    // To avoid the IO failure being ignored silently, we manually call the present function
    root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir");
    println!("Result has been saved to {}", OUT_FILE_NAME);
    Ok(())
}

fn get_data() -> String {
    String::from(
        "
 1.1.1.1	wireless	41.6
 1.1.1.1	wireless	32.5
 1.1.1.1	wireless	33.1
 1.1.1.1	wireless	32.3
 1.1.1.1	wireless	36.7
 1.1.1.1	wireless	32.0
 1.1.1.1	wireless	33.1
 1.1.1.1	wireless	32.0
 1.1.1.1	wireless	32.9
 1.1.1.1	wireless	32.7
 1.1.1.1	wireless	34.5
 1.1.1.1	wireless	36.5
 1.1.1.1	wireless	31.9
 1.1.1.1	wireless	33.7
 1.1.1.1	wireless	32.6
 1.1.1.1	wireless	35.1
 8.8.8.8	wireless	42.3
 8.8.8.8	wireless	32.9
 8.8.8.8	wireless	32.9
 8.8.8.8	wireless	34.3
 8.8.8.8	wireless	32.0
 8.8.8.8	wireless	33.3
 8.8.8.8	wireless	31.5
 8.8.8.8	wireless	33.1
 8.8.8.8	wireless	33.2
 8.8.8.8	wireless	35.9
 8.8.8.8	wireless	42.3
 8.8.8.8	wireless	34.1
 8.8.8.8	wireless	34.2
 8.8.8.8	wireless	34.2
 8.8.8.8	wireless	32.4
 8.8.8.8	wireless	33.0
 1.1.1.1	wired	31.8
 1.1.1.1	wired	28.6
 1.1.1.1	wired	29.4
 1.1.1.1	wired	28.8
 1.1.1.1	wired	28.2
 1.1.1.1	wired	28.8
 1.1.1.1	wired	28.4
 1.1.1.1	wired	28.6
 1.1.1.1	wired	28.3
 1.1.1.1	wired	28.5
 1.1.1.1	wired	28.5
 1.1.1.1	wired	28.5
 1.1.1.1	wired	28.4
 1.1.1.1	wired	28.6
 1.1.1.1	wired	28.4
 1.1.1.1	wired	28.9
 8.8.8.8	wired	33.3
 8.8.8.8	wired	28.4
 8.8.8.8	wired	28.7
 8.8.8.8	wired	29.1
 8.8.8.8	wired	29.6
 8.8.8.8	wired	28.9
 8.8.8.8	wired	28.6
 8.8.8.8	wired	29.3
 8.8.8.8	wired	28.6
 8.8.8.8	wired	29.1
 8.8.8.8	wired	28.7
 8.8.8.8	wired	28.3
 8.8.8.8	wired	28.3
 8.8.8.8	wired	28.6
 8.8.8.8	wired	29.4
 8.8.8.8	wired	33.1
",
    )
}
#[test]
fn entry_point() {
    main().unwrap()
}
