/*
 *  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 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
