/*
 * SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
 * SPDX-License-Identifier: BSD-2-Clause
 */

#![allow(clippy::panic_in_result_fn)]

use std::collections::HashMap;
use std::fs;
use std::io::Error as IoError;

use anyhow::{anyhow, Context, Result as AnyResult};
use once_cell::sync::Lazy;
use serde::Deserialize;
use serde_json::Error as SerdeJsonError;
use thiserror::Error;

use super::LanguagesDetect;

#[derive(Debug, Error)]
enum TestError {
    #[error("Could not read tests/data.json")]
    FileRead(#[source] IoError),

    #[error("Could not parse tests/data.json")]
    FileParse(#[source] SerdeJsonError),
}

#[derive(Debug, Deserialize)]
struct TDataLang {
    env: HashMap<String, String>,
    expected: Vec<String>,
}

#[derive(Debug, Deserialize)]
struct TData {
    languages: Vec<TDataLang>,
}

fn load_test_data() -> Result<TData, TestError> {
    let contents: String = fs::read_to_string("tests/data.json").map_err(TestError::FileRead)?;
    serde_json::from_str(&contents).map_err(TestError::FileParse)
}

fn get_test_data() -> AnyResult<&'static TData> {
    static TEST_DATA: Lazy<Result<TData, TestError>> = Lazy::new(load_test_data);
    TEST_DATA
        .as_ref()
        .map_err(|err| anyhow!("Could not load the test data: {err}"))
}

#[test]
fn test_preferred() -> AnyResult<()> {
    for tcase in &get_test_data()?.languages {
        assert_eq!(
            LanguagesDetect::new()
                .with_env(tcase.env.clone())
                .detect()
                .with_context(|| format!(
                    "Could not determine the list of preferred languages for {tcase:?}"
                ))?,
            tcase.expected
        );
    }
    Ok(())
}
