// SPDX-FileCopyrightText: 2023 Misato Kano <me@mirror-kt.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
//! Generators related to file usage
//!
//! See the [`FileUsage`] and [`FilesInPage`] type documentation
//! for specifics.

use super::{Generator, ParamValue, SortDirection};

/// Get all pages that use the given files.
///
/// See [API documentation](https://www.mediawiki.org/wiki/API:Fileusage) for more details.
#[derive(Generator)]
#[params(generator = "fileusage", gfulimit = "max")]
pub struct FileUsage {
    #[param("titles")]
    titles: Vec<String>,
    #[param("gfunamespaces")]
    namespaces: Option<Vec<u32>>,
    #[param("gfushow")]
    filter: Option<Filter>,
}

pub enum Filter {
    Redirect,
    NonRedirect,
}

impl ParamValue for Filter {
    fn stringify(&self) -> String {
        match self {
            Self::Redirect => "redirect",
            Self::NonRedirect => "!redirect",
        }
        .to_string()
    }
}

/// Get all embedded media files on provided pages.
///
/// See [API documentation](https://www.mediawiki.org/wiki/API:Images) for more details.
#[derive(Generator)]
#[params(generator = "images", gimlimit = "max")]
pub struct FilesInPage {
    #[param("titles")]
    titles: Vec<String>,
    #[param("gimimages")]
    images: Option<Vec<String>>,
    #[param("gimdir")]
    dir: Option<SortDirection>,
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::tests::testwp;

    #[tokio::test]
    async fn test_file_usage() {
        let bot = testwp().await;
        let gen = FileUsage::new(vec!["File:A_keyboard.jpg".to_string()]);
        dbg!(gen.params());
        let mut pages = gen.generate(&bot);

        let mut found = Vec::new();

        while let Some(page) = pages.recv().await {
            let page = page.unwrap();
            dbg!(page.title());

            found.push(page.title().to_string());
        }

        assert!(found.contains(&"Mwbot-rs/FileUsage".to_string()));
    }

    #[tokio::test]
    async fn test_files_in_page() {
        let bot = testwp().await;
        let gen = FilesInPage::new(vec!["Mwbot-rs/FileUsage".to_string()]);
        dbg!(gen.params());
        let mut pages = gen.generate(&bot);

        let mut found = Vec::new();

        while let Some(page) = pages.recv().await {
            let page = page.unwrap();
            dbg!(page.title());

            found.push(page.title().to_string());
        }

        assert_eq!(found, ["File:A keyboard.jpg".to_string()]);
    }
}
