use std::assert_matches;

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

#[test]
fn should_treat_nulls_as_optional_fields() {
    const TARIFF: &str = r#"{
        "id": "21",
        "currency": "EUR",
        "elements": [
            {
                "restrictions": null,
                "price_components": [
                    {
                        "type": "TIME",
                        "price": "3.0000",
                        "step_size": 60
                    },
                    {
                        "type": "PARKING_TIME",
                        "price": "5.0000",
                        "step_size": 300
                    }
                ]
            }
        ],
        "party_id": "ALL",
        "country_code": "DE",
        "last_updated": "2018-12-17T17:00:43Z",
        "end_date_time": "2029-06-30T23:59:59Z",
        "start_date_time": "2019-06-30T23:59:59Z"
    }"#;

    let doc = json::parse(TARIFF.into()).unwrap();
    let (_tariff, warnings) = crate::tariff::v221::Tariff::from_json(doc.root())
        .unwrap()
        .into_parts();

    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());
}

#[test]
fn should_parse_restrictions_empty_object() {
    const JSON: &str = "{}";

    let doc = json::parse(JSON.into()).unwrap();
    let (restrictions, warnings) = Restrictions::from_json(doc.root()).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());

    assert_matches!(
        restrictions,
        Restrictions {
            start_time: None,
            end_time: None,
            start_date: None,
            end_date: None,
            min_current: None,
            max_current: None,
            min_kwh: None,
            max_kwh: None,
            min_power: None,
            max_power: None,
            min_duration: None,
            max_duration: None,
            day_of_week: None,
            reservation: None
        }
    );
}

#[test]
fn should_parse_restrictions_all_null() {
    const JSON: &str = r#"{
            "start_time": null,
            "end_time": null,
            "start_date": null,
            "end_date": null,
            "min_current": null,
            "max_current": null,
            "min_kwh": null,
            "max_kwh": null,
            "min_power": null,
            "max_power": null,
            "min_duration": null,
            "max_duration": null,
            "days_of_week": null
        }"#;

    let doc = json::parse(JSON.into()).unwrap();
    let (restrictions, warnings) = Restrictions::from_json(doc.root()).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());

    assert_matches!(
        restrictions,
        Restrictions {
            start_time: None,
            end_time: None,
            start_date: None,
            end_date: None,
            min_current: None,
            max_current: None,
            min_kwh: None,
            max_kwh: None,
            min_power: None,
            max_power: None,
            min_duration: None,
            max_duration: None,
            day_of_week: None,
            reservation: None
        }
    );
}

#[test]
fn should_parse_restrictions_day_of_week_empty() {
    const JSON: &str = r#"{
            "start_time": null,
            "end_time": null,
            "start_date": null,
            "end_date": null,
            "min_current": null,
            "max_current": null,
            "min_kwh": null,
            "max_kwh": null,
            "min_power": null,
            "max_power": null,
            "min_duration": null,
            "max_duration": null,
            "days_of_week": []
        }"#;

    let doc = json::parse(JSON.into()).unwrap();
    let (restrictions, warnings) = Restrictions::from_json(doc.root()).unwrap().into_parts();
    assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());

    assert_matches!(
        restrictions,
        Restrictions {
            start_time: None,
            end_time: None,
            start_date: None,
            end_date: None,
            min_current: None,
            max_current: None,
            min_kwh: None,
            max_kwh: None,
            min_power: None,
            max_power: None,
            min_duration: None,
            max_duration: None,
            day_of_week: None,
            reservation: None
        }
    );
}
