/*
Copyright (C) 2023 Kunal Mehta <legoktm@debian.org>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

use std::collections::HashMap;
use std::path::PathBuf;

/// Builder to construct a request for file uploads
pub struct UploadRequest {
    pub(crate) comment: Option<String>,
    pub(crate) tags: Vec<String>,
    pub(crate) text: Option<String>,
    pub(crate) ignore_warnings: bool,
    pub(crate) file: PathBuf,
    pub(crate) chunk_size: usize,
}

impl UploadRequest {
    /// Upload a file that is at the specified path
    pub fn from_path(path: PathBuf) -> Self {
        Self {
            comment: None,
            tags: vec![],
            text: None,
            ignore_warnings: false,
            file: path,
            chunk_size: 5_000_000,
        }
    }

    /// Set the upload comment
    pub fn comment(mut self, comment: String) -> Self {
        self.comment = Some(comment);
        self
    }

    /// Add tags to the edit and upload entry
    pub fn tags(mut self, tags: Vec<String>) -> Self {
        self.tags.extend(tags);
        self
    }

    /// If this is a new page, specify the initial wikitext
    pub fn text(mut self, text: String) -> Self {
        self.text = Some(text);
        self
    }

    /// Ignore any upload warnings
    pub fn ignore_warnings(mut self, val: bool) -> Self {
        self.ignore_warnings = val;
        self
    }

    /// Set the chunk size, in bytes. By default it is
    /// 5MB (`5_000_000`).
    pub fn chunk_size(mut self, val: usize) -> Self {
        self.chunk_size = val;
        self
    }

    pub(crate) fn params(&self) -> HashMap<&'static str, String> {
        let mut params = HashMap::new();
        if let Some(comment) = &self.comment {
            params.insert("comment", comment.to_string());
        }
        if !self.tags.is_empty() {
            params.insert("tags", self.tags.join("|"));
        }
        if let Some(text) = &self.text {
            params.insert("text", text.to_string());
        }
        params
    }
}
