// Copyright 2014 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#define __STDC_LIMIT_MACROS
#include "android/base/Log.h"

#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

namespace android {
namespace base {

namespace {

// The current log output.
testing::LogOutput* gLogOutput = NULL;

bool gDcheckLevel = false;

// Convert a severity level into a string.
const char* severityLevelToString(LogSeverity severity) {
    const char* kSeverityStrings[] = {
        "INFO", "WARNING", "ERROR", "FATAL",
    };
    if (severity >= 0 && severity < LOG_NUM_SEVERITIES)
        return kSeverityStrings[severity];
    return "UNKNOWN";
}

// Default log output function
void defaultLogMessage(const LogParams& params,
                       const char* message,
                       size_t messageLen) {
    fprintf(stderr,
            "%s:%s:%d:%.*s\n",
            severityLevelToString(params.severity),
            params.file,
            params.lineno,
            int(messageLen),
            message);
    // Note: by default, stderr is non buffered, but the program might
    // have altered this setting, so always flush explicitly to ensure
    // that the log is displayed as soon as possible. This avoids log
    // messages being lost when a crash happens, and makes debugging
    // easier. On the other hand, it means lots of logging will impact
    // performance.
    fflush(stderr);

    if (params.severity >= LOG_FATAL)
        exit(1);
}

void logMessage(const LogParams& params,
                const char* message,
                size_t messageLen) {
    if (gLogOutput) {
        gLogOutput->logMessage(params, message, messageLen);
    } else {
        defaultLogMessage(params, message, messageLen);
    }
}

}  // namespace

// DCHECK level.

bool dcheckIsEnabled() {
    return gDcheckLevel;
}

bool setDcheckLevel(bool enabled) {
    bool ret = gDcheckLevel;
    gDcheckLevel = enabled;
    return ret;
}

// LogSeverity

LogSeverity getMinLogLevel() {
    return 0;
}

// LogString

LogString::LogString(const char* fmt, ...) : mString(NULL) {
    size_t capacity = 100;
    char* message = reinterpret_cast<char*>(::malloc(capacity));
    for (;;) {
        va_list args;
        va_start(args, fmt);
        int ret = vsnprintf(message, capacity, fmt, args);
        va_end(args);
        if (ret >= 0 && size_t(ret) < capacity)
            break;
        capacity *= 2;
    }
    mString = message;
}

LogString::~LogString() {
    ::free(mString);
}

// LogStream

LogStream::LogStream(const char* file, int lineno, LogSeverity severity) :
        mParams(file, lineno, severity),
        mString(NULL),
        mSize(0),
        mCapacity(0) {}

LogStream::~LogStream() {
    mSize = 0;
    mCapacity = 0;
    ::free(mString);
}

LogStream& LogStream::operator<<(char ch) {
    if (ch >= 32 && ch < 127) {
        append(&ch, 1U);
    } else {
        char temp[5];
        snprintf(temp, sizeof temp, "\\x%02x", ch);
        append(temp, 4U);
    }
    return *this;
}

LogStream& LogStream::operator<<(const void* ptr) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%p", ptr);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(int v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%d", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(unsigned v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%u", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(long v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%ld", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(unsigned long v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%lu", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(long long v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%lld", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

LogStream& LogStream::operator<<(unsigned long long v) {
    char temp[20];
    int ret = snprintf(temp, sizeof temp, "%llu", v);
    append(temp, static_cast<size_t>(ret));
    return *this;
}

void LogStream::append(const char* str) {
    if (str && str[0])
        append(str, strlen(str));
}

void LogStream::append(const char* str, size_t len) {
    if (!len || len > INT32_MAX)
        return;

    size_t newSize = mSize + len;
    if (newSize > mCapacity) {
        size_t newCapacity = mCapacity;
        while (newCapacity < newSize)
            newCapacity += (newCapacity >> 2) + 32;
        mString = reinterpret_cast<char*>(
                ::realloc(mString, newCapacity + 1));
        mCapacity = newCapacity;
    }
    ::memcpy(mString + mSize, str, len);
    mSize += len;
    mString[mSize] = '\0';
}

// LogMessage

LogMessage::LogMessage(const char* file, int line, LogSeverity severity) :
        mStream(new LogStream(file, line, severity)) {}

LogMessage::~LogMessage() {
    logMessage(mStream->params(),
               mStream->string(),
               mStream->size());
    delete mStream;
}

// ErrnoLogMessage

ErrnoLogMessage::ErrnoLogMessage(const char* file,
                                 int line,
                                 LogSeverity severity,
                                 int errnoCode) :
        mStream(NULL), mErrno(errnoCode) {
    mStream = new LogStream(file, line, severity);
}

ErrnoLogMessage::~ErrnoLogMessage() {
    (*mStream) << "Error message: " << strerror(mErrno);
    logMessage(mStream->params(),
               mStream->string(),
               mStream->size());
    delete mStream;
    // Restore the errno.
    errno = mErrno;
}

// LogOutput

namespace testing {

// static
LogOutput* LogOutput::setNewOutput(LogOutput* newOutput) {
    LogOutput* ret = gLogOutput;
    gLogOutput = newOutput;
    return ret;
}

}  // namespace testing

}  // naemspace base
}  // namespace android