/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <list>
#include <map>
#include <set>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

#include "log.h"

NEXTPNR_NAMESPACE_BEGIN

NPNR_NORETURN void logv_error(const char *format, va_list ap) NPNR_ATTRIBUTE(noreturn);

std::vector<FILE *> log_files;
std::vector<std::ostream *> log_streams;
FILE *log_errfile = NULL;
log_write_type log_write_function = nullptr;

bool log_error_stderr = false;
bool log_cmd_error_throw = false;
bool log_quiet_warnings = false;
std::string log_last_error;
void (*log_error_atexit)() = NULL;

// static bool next_print_log = false;
static int log_newline_count = 0;

std::string stringf(const char *fmt, ...)
{
    std::string string;
    va_list ap;

    va_start(ap, fmt);
    string = vstringf(fmt, ap);
    va_end(ap);

    return string;
}

std::string vstringf(const char *fmt, va_list ap)
{
    std::string string;
    char *str = NULL;

#ifdef _WIN32
    int sz = 64 + strlen(fmt), rc;
    while (1) {
        va_list apc;
        va_copy(apc, ap);
        str = (char *)realloc(str, sz);
        rc = vsnprintf(str, sz, fmt, apc);
        va_end(apc);
        if (rc >= 0 && rc < sz)
            break;
        sz *= 2;
    }
#else
    if (vasprintf(&str, fmt, ap) < 0)
        str = NULL;
#endif

    if (str != NULL) {
        string = str;
        free(str);
    }

    return string;
}

void logv(const char *format, va_list ap)
{
    //
    // Trim newlines from the beginning
    while (format[0] == '\n' && format[1] != 0) {
        log_always("\n");
        format++;
    }

    std::string str = vstringf(format, ap);

    if (str.empty())
        return;

    size_t nnl_pos = str.find_last_not_of('\n');
    if (nnl_pos == std::string::npos)
        log_newline_count += str.size();
    else
        log_newline_count = str.size() - nnl_pos - 1;

    for (auto f : log_files)
        fputs(str.c_str(), f);

    for (auto f : log_streams)
        *f << str;
    if (log_write_function)
        log_write_function(str);
}

void logv_info(const char *format, va_list ap)
{
    std::string message = vstringf(format, ap);

    log_always("Info: %s", message.c_str());
    log_flush();
}

void logv_warning(const char *format, va_list ap)
{
    std::string message = vstringf(format, ap);

    log_always("Warning: %s", message.c_str());
    log_flush();
}

void logv_warning_noprefix(const char *format, va_list ap)
{
    std::string message = vstringf(format, ap);

    log_always("%s", message.c_str());
}

void logv_error(const char *format, va_list ap)
{
#ifdef EMSCRIPTEN
    auto backup_log_files = log_files;
#endif

    if (log_errfile != NULL)
        log_files.push_back(log_errfile);

    if (log_error_stderr)
        for (auto &f : log_files)
            if (f == stdout)
                f = stderr;

    log_last_error = vstringf(format, ap);
    log_always("ERROR: %s", log_last_error.c_str());
    log_flush();

    if (log_error_atexit)
        log_error_atexit();

#ifdef EMSCRIPTEN
    log_files = backup_log_files;
#endif
    throw log_execution_error_exception();
}

void log_always(const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    logv(format, ap);
    va_end(ap);
}

void log(const char *format, ...)
{
    if (log_quiet_warnings) return;
    va_list ap;
    va_start(ap, format);
    logv(format, ap);
    va_end(ap);
}

void log_info(const char *format, ...)
{
    if (log_quiet_warnings) return;
    va_list ap;
    va_start(ap, format);
    logv_info(format, ap);
    va_end(ap);
}

void log_warning(const char *format, ...)
{
    if (log_quiet_warnings) return;
    va_list ap;
    va_start(ap, format);
    logv_warning(format, ap);
    va_end(ap);
}

void log_warning_noprefix(const char *format, ...)
{
    if (log_quiet_warnings) return;
    va_list ap;
    va_start(ap, format);
    logv_warning_noprefix(format, ap);
    va_end(ap);
}

void log_error(const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    logv_error(format, ap);
}

void log_cmd_error(const char *format, ...)
{
    va_list ap;
    va_start(ap, format);

    if (log_cmd_error_throw) {
        log_last_error = vstringf(format, ap);
        log_always("ERROR: %s", log_last_error.c_str());
        log_flush();
        throw log_cmd_error_exception();
    }

    logv_error(format, ap);
}

void log_break()
{
    if (log_quiet_warnings) return;
    if (log_newline_count < 2)
        log_always("\n");
    if (log_newline_count < 2)
        log_always("\n");
}

void log_flush()
{
    for (auto f : log_files)
        fflush(f);

    for (auto f : log_streams)
        f->flush();
}

NEXTPNR_NAMESPACE_END
