// SPDX-FileCopyrightText: 2023 Misato Kano <me@mirror-kt.dev>
// SPDX-License-Identifier: GPL-3.0-or-later
//! Generator to get user contributions
//!
//! See the [`UserContribs`] type documentation for specifics.
use super::{Generator, ParamValue};
use crate::{Bot, Result};
use mwapi_responses::query;
use mwtimestamp::Timestamp;

#[query(
    list = "usercontribs",
    ucprop = "ids|title|timestamp|comment|flags|tags"
)]
pub struct UserContribsResponse {}

/// List a user's contributions.
///
/// See [API documentation](https://www.mediawiki.org/wiki/API:Usercontribs) for more details.
#[derive(Generator)]
#[params(
    list = "usercontribs",
    uclimit = "max",
    ucprop = "ids|title|timestamp|comment|flags|tags"
)]
#[generator(
    return_type = "UserContribsResponseItem",
    response_type = "UserContribsResponse",
    transform_fn = "transform"
)]
pub struct UserContribs {
    #[param("ucstart")]
    start: Option<Timestamp>,
    #[param("ucend")]
    end: Option<Timestamp>,
    #[param("ucuser")]
    users: Option<Vec<String>>,
    #[param("ucuserids")]
    user_ids: Option<Vec<u64>>,
    #[param("ucuserprefix")]
    user_prefix: Option<String>,
    #[param("uciprange")]
    user_ip_range: Option<String>,
    #[param("ucdir")]
    dir: Option<Direction>,
    #[param("ucnamespace")]
    namespaces: Option<Vec<u32>>,
    #[param("ucshow")]
    filter: Option<Vec<String>>,
    #[param("uctag")]
    tags: Option<Vec<String>>,
}

fn transform(
    _bot: &Bot,
    item: UserContribsResponseItem,
) -> Result<UserContribsResponseItem> {
    Ok(item)
}

pub enum Direction {
    Newer,
    Older,
}

impl ParamValue for Direction {
    fn stringify(&self) -> String {
        match self {
            Self::Newer => "newer",
            Self::Older => "older",
        }
        .to_string()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::tests::testwp;
    use chrono::{TimeZone, Utc};

    #[tokio::test]
    async fn test_user_contrib() {
        let bot = testwp().await;
        let datetime = Utc.with_ymd_and_hms(2023, 5, 29, 3, 25, 6).unwrap();
        let gen = UserContribs::new()
            .users(vec!["Legoktm".to_string()])
            .start(datetime)
            .end(datetime);

        let mut logs = gen.generate(&bot);

        let log = logs.recv().await.unwrap().unwrap();

        assert_eq!(log.user, "Legoktm");
        assert_eq!(*log.timestamp, datetime);
        assert_eq!(log.title, "User:Legoktm/masto-collab");
        assert_eq!(log.revid, 571687);

        assert!(logs.recv().await.is_none());
    }
}
