use std::fs::File;

use jimtcl::{Interp, JimError, JimObject, JimResult, check_or_error};
use serde::de::DeserializeSeed;
use serde_json::de::{IoRead, SliceRead};

pub(crate) fn parse_json<'jim>(
    interp: &'jim Interp,
    args: &[JimObject<'jim>],
) -> JimResult<JimObject<'jim>> {
    let usage = "usage: parse json ?-file? <input>";
    check_or_error!(args.len() >= 2, usage);
    if args[1].as_str()? == "-file" {
        check_or_error!(args.len() == 3, usage);
        let open = File::open(args[2].as_str()?)?;
        let read = IoRead::new(open);
        json_from_input(interp, read)
    } else {
        check_or_error!(args.len() == 2, usage);
        let data = args[1].as_bytes();
        let read = SliceRead::new(data);
        json_from_input(interp, read)
    }
}

fn json_from_input<'jim, 'r, R: serde_json::de::Read<'r>>(
    interp: &'jim Interp,
    read: R,
) -> JimResult<JimObject<'jim>> {
    let mut de = serde_json::Deserializer::new(read);
    interp.deserialize(&mut de).map_err(JimError::wrap)
}
