module lunch.logger;

import std.stdio;
import std.format;
import lunch.conf;


private shared string _log;

void _writefln(Char, Args...)(string file, size_t line, Char[] fmt, Args args) @trusted
{
    synchronized
    {
        _log ~= format("%s:%d ", file, line) ~ format(fmt, args) ~ '\n';
        if (config.app.talkative)
            writefln(fmt, args);
    }
}

string log() @trusted
{
    return _log;
}


void infof(Char, Args...)(Char[] fmt, Args args, string file = __FILE__, size_t line = __LINE__) @safe
{
    _writefln(file, line, format("[INFO] %s", fmt), args);
}

void info(Char)(Char[] msg, string file = __FILE__, size_t line = __LINE__) @safe
{
    infof!(immutable char, Char[])("%s", msg, file, line);
}


void warnf(Char, Args...)(Char[] fmt, Args args, string file = __FILE__, size_t line = __LINE__) @safe
{
    _writefln(file, line, format("[WARN] %s", fmt), args);
}

void warn(Char)(Char[] msg, string file = __FILE__, size_t line = __LINE__) @safe
{
    warnf!(immutable char, Char[])("%s", msg, file, line);
}


void warnef(Char, Args...)(Char[] fmt, Exception ex, Args args, string file = __FILE__, size_t line = __LINE__) @safe
{
    _writefln(file, line, format("[WARN] %s", fmt), args);
    _writefln(file, line, "[<==>] %s", ex);
}

void warne(Char)(Char[] msg, Exception ex, string file = __FILE__, size_t line = __LINE__) @safe
{
    warnef!(immutable char, Char[])("%s", ex, msg, file, line);
}


void errorf(E = Exception, Char, Args...)(Char[] fmt, Args args, string file = __FILE__, size_t line = __LINE__) @trusted
{
    _writefln(file, line, format("[ERRO] %s", fmt), args);
    E ex = new E(format(fmt, args), file, line);
    _writefln(file, line, "[<==>] %s", ex);
    throw ex;
}

void error(E = Exception, Char)(Char[] msg, string file = __FILE__, size_t line = __LINE__) @safe
{
    errorf!(E, immutable char, Char[])("%s", msg, file, line);
}


void erroref(Char, Args...)(Char[] fmt, Exception ex, Args args, string file = __FILE__, size_t line = __LINE__) @safe
{
    _writefln(file, line, format("[ERRO] %s", fmt), args);
    _writefln(file, line, "[<==>] %s", ex);
    throw ex;
}

void errore(Char)(Char[] msg, Exception ex, string file = __FILE__, size_t line = __LINE__) @safe
{
    erroref!(immutable char, Char[])("%s", ex, msg, file, line);
}
