<commit_before>use std::error::Error;

use tokio::runtime::Runtime;
use log::warn;
use hyper::{Uri, Body, Request};
use hyper::header::CONTENT_TYPE;
use hyper::client::{Client, HttpConnector};
use hyper_tls::HttpsConnector;

use crate::Notice;
use crate::AirbrakeConfig;

pub struct AirbrakeClient {
    client: Client<HttpsConnector<HttpConnector>>,
    config: AirbrakeConfig
}

impl AirbrakeClient {
    pub fn new(config: AirbrakeConfig) -> AirbrakeClient {
        let connector = HttpsConnector::new();
        let client = Client::builder().build(connector);

        AirbrakeClient {
            client: client,
            config: config
        }
    }

    fn request<T>(&self, uri: Uri, payload: T) -> Request<Body>
    where T: Into<Body>
    {
        Request::post(uri)
            .header(CONTENT_TYPE, "application/json")
            .body(payload.into())
            .unwrap()
    }

    async fn send(&self, request: Request<Body>) -> () {
        let response = self.client.request(request).await;
        match response {
            Ok ( response ) => (),
            Err ( x ) => warn!("notification failed")
        }
    }

    pub fn notify(&self, notice: Notice) {
        let endpoint = self.config.endpoint_uri();
        let request = self.request(endpoint, notice);

        let mut runtime = Runtime::new().unwrap();
        runtime.block_on(self.send(request));
    }
}

#[cfg(test)]
mod tests {
    use std::io::Error;
    use super::Notifier;
    use config::Config;

    #[test]<commit_msg>Set message on error that should never happen<commit_after>use std::error::Error;

use tokio::runtime::Runtime;
use log::warn;
use hyper::{Uri, Body, Request};
use hyper::header::CONTENT_TYPE;
use hyper::client::{Client, HttpConnector};
use hyper_tls::HttpsConnector;

use crate::Notice;
use crate::AirbrakeConfig;

pub struct AirbrakeClient {
    client: Client<HttpsConnector<HttpConnector>>,
    config: AirbrakeConfig
}

impl AirbrakeClient {
    pub fn new(config: AirbrakeConfig) -> AirbrakeClient {
        let connector = HttpsConnector::new();
        let client = Client::builder().build(connector);

        AirbrakeClient {
            client: client,
            config: config
        }
    }

    fn request<T>(&self, uri: Uri, payload: T) -> Request<Body>
    where T: Into<Body>
    {
        Request::post(uri)
            .header(CONTENT_TYPE, "application/json")
            .body(payload.into())
            .expect("Request creation failed unexpectedly")
    }

    async fn send(&self, request: Request<Body>) -> () {
        let response = self.client.request(request).await;
        match response {
            Ok ( response ) => (),
            Err ( x ) => warn!("notification failed")
        }
    }

    pub fn notify(&self, notice: Notice) {
        let endpoint = self.config.endpoint_uri();
        let request = self.request(endpoint, notice);

        let mut runtime = Runtime::new().unwrap();
        runtime.block_on(self.send(request));
    }
}

#[cfg(test)]
mod tests {
    use std::io::Error;
    use super::Notifier;
    use config::Config;

    #[test]
{'fraction_non_alphanumeric': 0.13773222293401666, 'fraction_numerical': 0.0, 'mean_word_length': 2.7581227436823106, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, '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': '1247711', 'n_tokens_mistral': 929, 'n_tokens_neox': 932, 'n_words': 217}