<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 <NAME> <<EMAIL>> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::io::Write;
use std::io::stderr;
use std::collections::BTreeMap;

use configuration::Configuration;
use error::RuntimeErrorKind as EK;
use error::RuntimeError as RE;
use error::ResultExt;
use runtime::Runtime;

use clap::ArgMatches;
use log::{Log, LogLevel, LogRecord, LogMetadata};
use toml::Value;
use toml_query::read::TomlValueReadExt;
use handlebars::Handlebars;

type ModuleName = String;
type Result<T> = ::std::result::Result<T, RE>;

enum LogDestination {
    Stderr,
    File(::std::fs::File),
}

impl Default for LogDestination {
    fn default() -> LogDestination {
        LogDestination::Stderr
    }
}

struct ModuleSettings {
    enabled:        bool,
    level:          Option<LogLevel>,

    #[allow(unused)]
    destinations:   Option<Vec<LogDestination>>,
}

/// Logger implementation for `log` crate.
pub struct ImagLogger {
    global_loglevel     : LogLevel,

    #[allow(unused)]
    global_destinations : Vec<LogDestination>,
    // global_format_trace : ,
    // global_format_debug : ,
    // global_format_info  : ,
    // global_format_warn  : ,
    // global_format_error : ,
    module_settings     : BTreeMap<ModuleName, ModuleSettings>,

    handlebars: Handlebars,
}

impl ImagLogger {

    /// Create a new ImagLogger object with a certain level
    pub fn new(matches: &ArgMatches, config: Option<&Configuration>) -> Result<ImagLogger> {
        let mut handlebars = Handlebars::new();

        handlebars.register_helper("black"  , Box::new(self::template_helpers::ColorizeBlackHelper));
        handlebars.register_helper("blue"   , Box::new(self::template_helpers::ColorizeBlueHelper));
        handlebars.register_helper("cyan"   , Box::new(self::template_helpers::ColorizeCyanHelper));
        handlebars.register_helper("green"  , Box::new(self::template_helpers::ColorizeGreenHelper));
        handlebars.register_helper("purple" , Box::new(self::template_helpers::ColorizePurpleHelper));
        handlebars.register_helper("red"    , Box::new(self::template_helpers::ColorizeRedHelper));
        handlebars.register_helper("white"  , Box::new(self::template_helpers::ColorizeWhiteHelper));
        handlebars.register_helper("yellow" , Box::new(self::template_helpers::ColorizeYellowHelper));

        handlebars.register_helper("underline"     , Box::new(self::template_helpers::UnderlineHelper));
        handlebars.register_helper("bold"          , Box::new(self::template_helpers::BoldHelper));
        handlebars.register_helper("blink"         , Box::new(self::template_helpers::BlinkHelper));
        handlebars.register_helper("strikethrough" , Box::new(self::template_helpers::StrikethroughHelper));

        {
            let fmt = try!(aggregate_global_format_trace(matches, config));
            try!(handlebars.register_template_string("TRACE", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_debug(matches, config));
            try!(handlebars.register_template_string("DEBUG", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_info(matches, config));
            try!(handlebars.register_template_string("INFO", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_warn(matches, config));
            try!(handlebars.register_template_string("WARN", fmt)); // name must be uppercase
        }
        {<commit_msg>Register the no-escape escape functionality in handlebars<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 <NAME> <<EMAIL>> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::io::Write;
use std::io::stderr;
use std::collections::BTreeMap;

use configuration::Configuration;
use error::RuntimeErrorKind as EK;
use error::RuntimeError as RE;
use error::ResultExt;
use runtime::Runtime;

use clap::ArgMatches;
use log::{Log, LogLevel, LogRecord, LogMetadata};
use toml::Value;
use toml_query::read::TomlValueReadExt;
use handlebars::Handlebars;

type ModuleName = String;
type Result<T> = ::std::result::Result<T, RE>;

enum LogDestination {
    Stderr,
    File(::std::fs::File),
}

impl Default for LogDestination {
    fn default() -> LogDestination {
        LogDestination::Stderr
    }
}

struct ModuleSettings {
    enabled:        bool,
    level:          Option<LogLevel>,

    #[allow(unused)]
    destinations:   Option<Vec<LogDestination>>,
}

/// Logger implementation for `log` crate.
pub struct ImagLogger {
    global_loglevel     : LogLevel,

    #[allow(unused)]
    global_destinations : Vec<LogDestination>,
    // global_format_trace : ,
    // global_format_debug : ,
    // global_format_info  : ,
    // global_format_warn  : ,
    // global_format_error : ,
    module_settings     : BTreeMap<ModuleName, ModuleSettings>,

    handlebars: Handlebars,
}

impl ImagLogger {

    /// Create a new ImagLogger object with a certain level
    pub fn new(matches: &ArgMatches, config: Option<&Configuration>) -> Result<ImagLogger> {
        let mut handlebars = Handlebars::new();

        handlebars.register_escape_fn(::handlebars::no_escape);

        handlebars.register_helper("black"  , Box::new(self::template_helpers::ColorizeBlackHelper));
        handlebars.register_helper("blue"   , Box::new(self::template_helpers::ColorizeBlueHelper));
        handlebars.register_helper("cyan"   , Box::new(self::template_helpers::ColorizeCyanHelper));
        handlebars.register_helper("green"  , Box::new(self::template_helpers::ColorizeGreenHelper));
        handlebars.register_helper("purple" , Box::new(self::template_helpers::ColorizePurpleHelper));
        handlebars.register_helper("red"    , Box::new(self::template_helpers::ColorizeRedHelper));
        handlebars.register_helper("white"  , Box::new(self::template_helpers::ColorizeWhiteHelper));
        handlebars.register_helper("yellow" , Box::new(self::template_helpers::ColorizeYellowHelper));

        handlebars.register_helper("underline"     , Box::new(self::template_helpers::UnderlineHelper));
        handlebars.register_helper("bold"          , Box::new(self::template_helpers::BoldHelper));
        handlebars.register_helper("blink"         , Box::new(self::template_helpers::BlinkHelper));
        handlebars.register_helper("strikethrough" , Box::new(self::template_helpers::StrikethroughHelper));

        {
            let fmt = try!(aggregate_global_format_trace(matches, config));
            try!(handlebars.register_template_string("TRACE", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_debug(matches, config));
            try!(handlebars.register_template_string("DEBUG", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_info(matches, config));
            try!(handlebars.register_template_string("INFO", fmt)); // name must be uppercase
        }
        {
            let fmt = try!(aggregate_global_format_warn(matches, config));
            try!(handlebars.register_template_string("WARN", fmt)); // name must be uppercase
        }
        {
{'fraction_non_alphanumeric': 0.11912693854106836, 'fraction_numerical': 0.004824813325674899, 'mean_word_length': 3.7651888341543516, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, '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': '5194589', 'n_tokens_mistral': 2446, 'n_tokens_neox': 2428, 'n_words': 599}