/** @file utils.cpp
 *
 *  @author Cory Alexander Balaton (coryab)
 *  @author Janita Ovidie Sandtrøen Willumsen (janitaws)
 *
 *  @version 1.0
 *
 *  @brief Implementation of the utils
 *
 *  @bug No known bugs
 * */
#include "utils.hpp"

std::string scientific_format(double d, int width, int prec)
{
    std::stringstream ss;
    ss << std::setw(width) << std::setprecision(prec) << std::scientific << d;
    return ss.str();
}

std::string scientific_format(const std::vector<double> &v, int width, int prec)
{
    std::stringstream ss;
    for (double elem : v) {
        ss << scientific_format(elem, width, prec);
    }
    return ss.str();
}

static void print_message(std::string msg)
{
    if (msg.size() > 0) {
        std::cout << "message: " << msg << "\n\n";
    }
    else {
        std::cout << "\n";
    }
}

void m_assert(bool expr, std::string expr_str, std::string f, std::string file,
              int line, std::string msg)
{
    std::string new_assert(f.size() + (expr ? 4 : 6), '-');
    std::cout << "\x1B[36m" << new_assert << "\033[0m\n";
    std::cout << f << ": ";
    if (expr) {
        std::cout << "\x1B[32mOK\033[0m\n";
        print_message(msg);
    }
    else {
        std::cout << "\x1B[31mFAIL\033[0m\n";
        print_message(msg);
        std::cout << file << " " << line << ": Assertion \"" << expr_str
                  << "\" Failed\n\n";
        abort();
    }
}

bool arma_vector_close_to(arma::vec &a, arma::vec &b, double tol)
{
    if (a.n_elem != b.n_elem) {
        return false;
    }

    for (int i = 0; i < a.n_elem; i++) {
        if (std::abs(a(i) - b(i)) >= tol) {
            return false;
        }
    }
    return true;
}
