/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team


All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

/** @file  DefaultLogger.cpp
 *  @brief Implementation of DefaultLogger (and Logger)
 */


// Default log streams
#include "Win32DebugLogStream.h"
#include "StdOStreamLogStream.h"
#include "FileLogStream.h"
#include "StringUtils.h"

#include <assimp/DefaultIOSystem.h>
#include <assimp/NullLogger.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/ai_assert.h>
#include <iostream>
#include <stdio.h>

#ifndef ASSIMP_BUILD_SINGLETHREADED
#   include <thread>
#   include <mutex>

std::mutex loggerMutex;
#endif

namespace Assimp    {

// ----------------------------------------------------------------------------------
NullLogger DefaultLogger::s_pNullLogger;
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;

static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;

// ----------------------------------------------------------------------------------
// Represents a log-stream + its error severity
struct LogStreamInfo
{
    unsigned int m_uiErrorSeverity;
    LogStream *m_pStream;

    // Constructor
    LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
        m_uiErrorSeverity( uiErrorSev ),
        m_pStream( pStream )
    {
        // empty
    }

    // Destructor
    ~LogStreamInfo()
    {
        delete m_pStream;
    }
};

// ----------------------------------------------------------------------------------
// Construct a default log stream
LogStream* LogStream::createDefaultStream(aiDefaultLogStream    streams,
    const char* name /*= "AssimpLog.txt"*/,
    IOSystem* io            /*= NULL*/)
{
    switch (streams)
    {
        // This is a platform-specific feature
    case aiDefaultLogStream_DEBUGGER:
#ifdef WIN32
        return new Win32DebugLogStream();
#else
        return NULL;
#endif

        // Platform-independent default streams
    case aiDefaultLogStream_STDERR:
        return new StdOStreamLogStream(std::cerr);
    case aiDefaultLogStream_STDOUT:
        return new StdOStreamLogStream(std::cout);
    case aiDefaultLogStream_FILE:
        return (name && *name ? new FileLogStream(name,io) : NULL);
    default:
        // We don't know this default log stream, so raise an assertion
        ai_assert(false);

    };

    // For compilers without dead code path detection
    return NULL;
}

// ----------------------------------------------------------------------------------
//  Creates the only singleton instance
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
    LogSeverity severity                       /*= NORMAL*/,
    unsigned int defStreams                    /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
    IOSystem* io                               /*= NULL*/)
{
    // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED
    std::lock_guard<std::mutex> lock(loggerMutex);
#endif

    if (m_pLogger && !isNullLogger() )
        delete m_pLogger;

    m_pLogger = new DefaultLogger( severity );

    // Attach default log streams
    // Stream the log to the MSVC debugger?
    if (defStreams & aiDefaultLogStream_DEBUGGER)
        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));

    // Stream the log to COUT?
    if (defStreams & aiDefaultLogStream_STDOUT)
        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));

    // Stream the log to CERR?
    if (defStreams & aiDefaultLogStream_STDERR)
         m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));

    // Stream the log to a file
    if (defStreams & aiDefaultLogStream_FILE && name && *name)
        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));

    return m_pLogger;
}

// ----------------------------------------------------------------------------------
void Logger::debug(const char* message) {

    // SECURITY FIX: otherwise it's easy to produce overruns since
    // sometimes importers will include data from the input file
    // (i.e. node names) in their messages.
    if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
        return;
    }
    return OnDebug(message);
}

// ----------------------------------------------------------------------------------
void Logger::info(const char* message)  {

    // SECURITY FIX: see above
    if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
        return;
    }
    return OnInfo(message);
}

// ----------------------------------------------------------------------------------
void Logger::warn(const char* message)  {

    // SECURITY FIX: see above
    if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
        return;
    }
    return OnWarn(message);
}

// ----------------------------------------------------------------------------------
void Logger::error(const char* message) {

    // SECURITY FIX: see above
    if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
        return;
    }
    return OnError(message);
}

// ----------------------------------------------------------------------------------
void DefaultLogger::set( Logger *logger )
{
    // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED
    std::lock_guard<std::mutex> lock(loggerMutex);
#endif

    if (!logger)logger = &s_pNullLogger;
    if (m_pLogger && !isNullLogger() )
        delete m_pLogger;

    DefaultLogger::m_pLogger = logger;
}

// ----------------------------------------------------------------------------------
bool DefaultLogger::isNullLogger()
{
    return m_pLogger == &s_pNullLogger;
}

// ----------------------------------------------------------------------------------
Logger *DefaultLogger::get() {
    return m_pLogger;
}

// ----------------------------------------------------------------------------------
//  Kills the only instance
void DefaultLogger::kill()
{
    // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED
    std::lock_guard<std::mutex> lock(loggerMutex);
#endif

	if ( m_pLogger == &s_pNullLogger ) {
		return;
	}
    delete m_pLogger;
    m_pLogger = &s_pNullLogger;
}

// ----------------------------------------------------------------------------------
//  Debug message
void DefaultLogger::OnDebug( const char* message )
{
	if ( m_Severity == Logger::NORMAL )
		return;

	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
	char msg[Size];
	ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);

    WriteToStreams( msg, Logger::Debugging );
}

// ----------------------------------------------------------------------------------
//  Logs an info
void DefaultLogger::OnInfo( const char* message )
{
	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
	char msg[Size];
    ai_snprintf(msg, Size, "Info,  T%u: %s", GetThreadID(), message );

    WriteToStreams( msg , Logger::Info );
}

// ----------------------------------------------------------------------------------
//  Logs a warning
void DefaultLogger::OnWarn( const char* message )
{
	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
	char msg[Size];
	ai_snprintf(msg, Size, "Warn,  T%u: %s", GetThreadID(), message );

    WriteToStreams( msg, Logger::Warn );
}

// ----------------------------------------------------------------------------------
//  Logs an error
void DefaultLogger::OnError( const char* message )
{
	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
	char msg[ Size ];
    ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message );

    WriteToStreams( msg, Logger::Err );
}

// ----------------------------------------------------------------------------------
//  Will attach a new stream
bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
{
    if (!pStream)
        return false;

    if (0 == severity)  {
        severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
    }

    for ( StreamIt it = m_StreamArray.begin();
        it != m_StreamArray.end();
        ++it )
    {
        if ( (*it)->m_pStream == pStream )
        {
            (*it)->m_uiErrorSeverity |= severity;
            return true;
        }
    }

    LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
    m_StreamArray.push_back( pInfo );
    return true;
}

// ----------------------------------------------------------------------------------
//  Detach a stream
bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{
    if (!pStream)
        return false;

    if (0 == severity)  {
        severity = SeverityAll;
    }

    for ( StreamIt it = m_StreamArray.begin();
        it != m_StreamArray.end();
        ++it )
    {
        if ( (*it)->m_pStream == pStream )
        {
            (*it)->m_uiErrorSeverity &= ~severity;
            if ( (*it)->m_uiErrorSeverity == 0 )
            {
                // don't delete the underlying stream 'cause the caller gains ownership again
                (**it).m_pStream = NULL;
                delete *it;
                m_StreamArray.erase( it );
                break;
            }
            return true;
        }
    }
    return false;
}

// ----------------------------------------------------------------------------------
//  Constructor
DefaultLogger::DefaultLogger(LogSeverity severity)
    :   Logger  ( severity )
    ,   noRepeatMsg (false)
    ,   lastLen( 0 )
{
    lastMsg[0] = '\0';
}

// ----------------------------------------------------------------------------------
//  Destructor
DefaultLogger::~DefaultLogger()
{
    for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
        // also frees the underlying stream, we are its owner.
        delete *it;
    }
}

// ----------------------------------------------------------------------------------
//  Writes message to stream
void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev )
{
    ai_assert(NULL != message);

    // Check whether this is a repeated message
    if (! ::strncmp( message,lastMsg, lastLen-1))
    {
        if (!noRepeatMsg)
        {
            noRepeatMsg = true;
            message = "Skipping one or more lines with the same contents\n";
        }
        else return;
    }
    else
    {
        // append a new-line character to the message to be printed
        lastLen = ::strlen(message);
        ::memcpy(lastMsg,message,lastLen+1);
        ::strcat(lastMsg+lastLen,"\n");

        message = lastMsg;
        noRepeatMsg = false;
        ++lastLen;
    }
    for ( ConstStreamIt it = m_StreamArray.begin();
        it != m_StreamArray.end();
        ++it)
    {
        if ( ErrorSev & (*it)->m_uiErrorSeverity )
            (*it)->m_pStream->write( message);
    }
}

// ----------------------------------------------------------------------------------
//  Returns thread id, if not supported only a zero will be returned.
unsigned int DefaultLogger::GetThreadID()
{
    // fixme: we can get this value via std::threads
    // std::this_thread::get_id().hash() returns a (big) size_t, not sure if this is useful in this case.
#ifdef WIN32
    return (unsigned int)::GetCurrentThreadId();
#else
    return 0; // not supported
#endif
}

// ----------------------------------------------------------------------------------

} // !namespace Assimp
