<commit_before>use std::collections::HashMap;
use command::{Command, Query};
use util;
use selectable::fragmentable::Fragmentable;
use selectable::fragmentable::{OrderedFragment, QueryFragment};
use types::drilldown_calc_type::CalcType;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LabeledDrilldown {
    label: String,
    arguments: HashMap<String, String>,
}

impl Default for LabeledDrilldown {
    fn default() -> LabeledDrilldown {
        LabeledDrilldown {
            label: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl LabeledDrilldown {
    pub fn new(label: String) -> LabeledDrilldown {
        let default: LabeledDrilldown = Default::default();
        LabeledDrilldown {
            label: label,
            arguments: default.arguments,
        }
    }

    pub fn keys(mut self, targets: Vec<String>) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "keys".to_string());
        let string = format!("\'{}\'", util::split_values_vec(targets));
        self.arguments.insert(key, string.clone());
        self
    }

    pub fn sortby(mut self, targets: Vec<String>) -> LabeledDrilldown {
        let string = format!("\'{}\'", util::split_values_vec(targets));
        let key = util::labeled_key(self.label.clone(), "sortby".to_string());
        self.arguments.insert(key, string.clone());
        self
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> LabeledDrilldown {
        let string = format!("\'{}\'", util::split_values_vec(columns));
        let key = util::labeled_key(self.label.clone(), "output_columns".to_string());

        self.arguments.insert(key, string.clone());
        self
    }

    pub fn offset(mut self, offset: i64) -> LabeledDrilldown {
        let offset = format!("{}", offset);
        let key = util::labeled_key(self.label.clone(), "offset".to_string());
        self.arguments.insert(key, offset.clone());
        self
    }

    pub fn limit(mut self, limit: i64) -> LabeledDrilldown {
        let limit = format!("{}", limit);
        let key = util::labeled_key(self.label.clone(), "limit".to_string());
        self.arguments.insert(key, limit.clone());
        self
    }

    pub fn calc_types(mut self, calc_types: CalcType) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "calc_types".to_string());
        let types = format!("{}", calc_types);
        self.arguments.insert(key, types);
        self
    }

    pub fn calc_target(mut self, target: String) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "calc_target".to_string());
        self.arguments.insert(key, target.clone());
        self
    }

    pub fn table(mut self, table: String) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "table".to_string());
        self.arguments.insert(key, table.clone());
        self
    }

    pub fn build(self) -> Query {
        let mut query: Query = vec![];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        query
    }
}

impl Fragmentable for LabeledDrilldown {
    fn to_fragment(self) -> (Command, OrderedFragment, QueryFragment) {
        // Command::Extension is `Command` type requirement. It should be ignored.
        (Command::Extension("labeled_drilldown".to_string()), vec![], self.arguments.clone())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::collections::HashMap;
    use command::Query;
    use types::drilldown_calc_type::CalcType;

    #[test]<commit_msg>labeled_drilldown: Add TODO<commit_after>use std::collections::HashMap;
use command::{Command, Query};
use util;
use selectable::fragmentable::Fragmentable;
use selectable::fragmentable::{OrderedFragment, QueryFragment};
use types::drilldown_calc_type::CalcType;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct LabeledDrilldown {
    label: String,
    arguments: HashMap<String, String>,
}

impl Default for LabeledDrilldown {
    fn default() -> LabeledDrilldown {
        LabeledDrilldown {
            label: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl LabeledDrilldown {
    pub fn new(label: String) -> LabeledDrilldown {
        let default: LabeledDrilldown = Default::default();
        LabeledDrilldown {
            label: label,
            arguments: default.arguments,
        }
    }

    pub fn keys(mut self, targets: Vec<String>) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "keys".to_string());
        let string = format!("\'{}\'", util::split_values_vec(targets));
        self.arguments.insert(key, string.clone());
        self
    }

    pub fn sortby(mut self, targets: Vec<String>) -> LabeledDrilldown {
        let string = format!("\'{}\'", util::split_values_vec(targets));
        let key = util::labeled_key(self.label.clone(), "sortby".to_string());
        self.arguments.insert(key, string.clone());
        self
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> LabeledDrilldown {
        let string = format!("\'{}\'", util::split_values_vec(columns));
        let key = util::labeled_key(self.label.clone(), "output_columns".to_string());

        self.arguments.insert(key, string.clone());
        self
    }

    pub fn offset(mut self, offset: i64) -> LabeledDrilldown {
        let offset = format!("{}", offset);
        let key = util::labeled_key(self.label.clone(), "offset".to_string());
        self.arguments.insert(key, offset.clone());
        self
    }

    pub fn limit(mut self, limit: i64) -> LabeledDrilldown {
        let limit = format!("{}", limit);
        let key = util::labeled_key(self.label.clone(), "limit".to_string());
        self.arguments.insert(key, limit.clone());
        self
    }

    pub fn calc_types(mut self, calc_types: CalcType) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "calc_types".to_string());
        let types = format!("{}", calc_types);
        self.arguments.insert(key, types);
        self
    }

    pub fn calc_target(mut self, target: String) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "calc_target".to_string());
        self.arguments.insert(key, target.clone());
        self
    }

    // TODO: where is the right place for pseudo-table?
    pub fn table(mut self, table: String) -> LabeledDrilldown {
        let key = util::labeled_key(self.label.clone(), "table".to_string());
        self.arguments.insert(key, table.clone());
        self
    }

    pub fn build(self) -> Query {
        let mut query: Query = vec![];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        query
    }
}

impl Fragmentable for LabeledDrilldown {
    fn to_fragment(self) -> (Command, OrderedFragment, QueryFragment) {
        // Command::Extension is `Command` type requirement. It should be ignored.
        (Command::Extension("labeled_drilldown".to_string()), vec![], self.arguments.clone())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::collections::HashMap;
    use command::Query;
    use types::drilldown_calc_type::CalcType;

    #[test]
{'fraction_non_alphanumeric': 0.15047879616963064, 'fraction_numerical': 0.001094391244870041, 'mean_word_length': 2.9583107742284787, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7231128', 'n_tokens_mistral': 2272, 'n_tokens_neox': 2244, 'n_words': 489}