//! The type that represents a request of `files.completeUploadExternal`.
//!
//! <https://api.slack.com/methods/files.completeUploadExternal>

use serde::Serialize;

/// The type that represents a request of `files.completeUploadExternal`.
///
/// <https://api.slack.com/methods/files.completeUploadExternal>
#[derive(Clone, Debug, Serialize)]
pub struct FilesCompleteUploadExternalRequest {
    /// Array of file ids and their corresponding (optional) titles.
    ///
    /// <https://api.slack.com/methods/files.completeUploadExternal#arg_files>
    pub files: Vec<FilesCompleteUploadExternalRequestFile>,

    /// Channel ID where the file will be shared.
    ///
    /// <https://api.slack.com/methods/files.completeUploadExternal#arg_channel_id>
    #[serde(skip_serializing_if = "Option::is_none")]
    pub channel_id: Option<String>,

    /// The message text introducing the file in specified `channels`.
    ///
    /// <https://api.slack.com/methods/files.completeUploadExternal#arg_initial_comment>
    #[serde(skip_serializing_if = "Option::is_none")]
    pub initial_comment: Option<String>,

    /// Provide another message's ts value to upload this file as a reply.
    ///
    /// <https://api.slack.com/methods/files.completeUploadExternal#arg_thread_ts>
    #[serde(skip_serializing_if = "Option::is_none")]
    pub thread_ts: Option<String>,
}

/// The type that represents a file ID and its corresponding (optional) title.
#[derive(Clone, Debug, Serialize)]
pub struct FilesCompleteUploadExternalRequestFile {
    /// The file ID.
    pub id: String,

    /// The file title.
    pub title: Option<String>,
}

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

    #[test]
    fn test_ser_files_complete_upload_external_request() -> anyhow::Result<()> {
        let testdata = FilesCompleteUploadExternalRequest {
            files: vec![FilesCompleteUploadExternalRequestFile {
                id: "F044GKUHN9Z".to_string(),
                title: Some("slack-test".to_string()),
            }],
            channel_id: Some("C0NF841BK".to_string()),
            initial_comment: Some("example initial_comment".to_string()),
            thread_ts: Some("1524523204.000192".to_string()),
        };
        let serialized = serde_json::to_string(&testdata)?;

        let deserialized: serde_json::Value = serde_json::from_str(&serialized)?;
        let files = &deserialized["files"][0];
        assert_eq!(files["id"], testdata.files.get(0).unwrap().id);
        assert_eq!(
            &files["title"],
            testdata.files.get(0).unwrap().title.as_ref().unwrap()
        );
        assert_eq!(deserialized["channel_id"], testdata.channel_id.unwrap());
        assert_eq!(
            deserialized["initial_comment"],
            testdata.initial_comment.unwrap()
        );
        assert_eq!(deserialized["thread_ts"], testdata.thread_ts.unwrap());

        Ok(())
    }
}
