#![allow(
    clippy::unwrap_in_result,
    reason = "unwraps are allowed anywhere in tests"
)]

use chrono::{DateTime, TimeZone as _, Utc};

use super::Warning;
use crate::{
    json::{self, FromJson as _},
    Verdict,
};

#[track_caller]
fn parse_timestamp_from_json(json: &'static str) -> Verdict<DateTime<Utc>, Warning> {
    let doc = json::parse(json.into()).unwrap();
    let date_time_time = doc.root().find_field("start_date_time").unwrap();
    DateTime::<Utc>::from_json(date_time_time.element())
}

#[test]
fn should_parse_utc_datetime() {
    const JSON: &str = r#"{ "start_date_time": "2015-06-29T22:39:09Z" }"#;

    let (datetime, warnings) = parse_timestamp_from_json(JSON).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());
    assert_eq!(
        datetime,
        Utc.with_ymd_and_hms(2015, 6, 29, 22, 39, 9).unwrap()
    );
}

#[test]
fn should_parse_timezone_to_utc() {
    const JSON: &str = r#"{ "start_date_time": "2015-06-29T22:39:09+02:00" }"#;

    let (datetime, warnings) = parse_timestamp_from_json(JSON).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());
    assert_eq!(
        datetime,
        Utc.with_ymd_and_hms(2015, 6, 29, 20, 39, 9).unwrap()
    );
}

#[test]
fn should_parse_timezone_naive_to_utc() {
    // This is a mess, but unfortunately OCPI 2.1.1 and 2.2 specify that datetimes without any
    // timezone specification are also allowed
    const JSON: &str = r#"{ "start_date_time": "2015-06-29T22:39:09" }"#;

    let (datetime, warnings) = parse_timestamp_from_json(JSON).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());

    assert_eq!(
        datetime,
        Utc.with_ymd_and_hms(2015, 6, 29, 22, 39, 9).unwrap()
    );
}
