use std::path::Path;

use assert_matches::assert_matches;

use crate::{
    guess,
    test::{self, read_file_content},
    ObjectType, Versioned as _,
};

use super::{cdr_version_and_report, tariff_version_with_report, Report};

#[test_each::file(
    glob = "ocpi-tariffs/test_data/v221/real_world/*/cdr*.json",
    name(segments = 2)
)]
fn should_guess_version_v221(cdr_json: &str, path: &Path) {
    test::setup();

    test_guess(crate::Version::V221, cdr_json, path);
}

#[test_each::file(glob = "ocpi-tariffs/test_data/v211/*/cdr*.json", name(segments = 2))]
fn should_guess_version_v211(cdr_json: &str, path: &Path) {
    test::setup();

    test_guess(crate::Version::V211, cdr_json, path);
}

#[track_caller]
fn test_guess(expected_version: crate::Version, cdr_json: &str, path: &Path) {
    {
        let Report {
            version: guess,
            unexpected_fields,
        } = cdr_version_and_report(cdr_json.into()).unwrap();

        let cdr = assert_matches!(guess, guess::Version::Certain ( cdr ) => cdr);
        assert_eq!(cdr.version(), expected_version);

        test::assert_no_unexpected_fields(ObjectType::Cdr, &unexpected_fields);
    }

    {
        let tariff_json = read_file_content(&path.parent().unwrap().join("tariff.json")).ok();

        if let Some(json) = tariff_json {
            let Report {
                version: guess,
                unexpected_fields,
            } = tariff_version_with_report((&*json).into()).unwrap();

            let tariff = assert_matches!(guess, guess::Version::Certain ( tariff ) => tariff);
            assert_eq!(tariff.version(), expected_version);

            test::assert_no_unexpected_fields(ObjectType::Tariff, &unexpected_fields);
        }
    }
}
