/*
 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
 */

#include "config.h"
#include "ConsoleClient.h"

#include "CatchScope.h"
#include "JSCJSValueInlines.h"
#include "JSGlobalObject.h"
#include "ScriptArguments.h"
#include "ScriptCallStack.h"
#include "ScriptCallStackFactory.h"
#include <wtf/Assertions.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>

using namespace Inspector;

namespace JSC {

static void appendURLAndPosition(StringBuilder& builder, const String& url, unsigned lineNumber, unsigned columnNumber)
{
    if (url.isEmpty())
        return;

    builder.append(url);

    if (lineNumber > 0)
        builder.append(':', lineNumber);

    if (columnNumber > 0)
        builder.append(':', columnNumber);
}

static void appendMessagePrefix(StringBuilder& builder, MessageSource source, MessageType type, MessageLevel level)
{
    String sourceString;
    switch (source) {
    case MessageSource::ConsoleAPI:
        // Default, no need to be more specific.
        break;
    case MessageSource::XML:
        sourceString = "XML"_s;
        break;
    case MessageSource::JS:
        sourceString = "JS"_s;
        break;
    case MessageSource::Network:
        sourceString = "NETWORK"_s;
        break;
    case MessageSource::Storage:
        sourceString = "STORAGE"_s;
        break;
    case MessageSource::AppCache:
        sourceString = "APPCACHE"_s;
        break;
    case MessageSource::Rendering:
        sourceString = "RENDERING"_s;
        break;
    case MessageSource::CSS:
        sourceString = "CSS"_s;
        break;
    case MessageSource::Security:
        sourceString = "SECURITY"_s;
        break;
    case MessageSource::ContentBlocker:
        sourceString = "CONTENTBLOCKER"_s;
        break;
    case MessageSource::Media:
        sourceString = "MEDIA"_s;
        break;
    case MessageSource::MediaSource:
        sourceString = "MEDIASOURCE"_s;
        break;
    case MessageSource::WebRTC:
        sourceString = "WEBRTC"_s;
        break;
    case MessageSource::ITPDebug:
        sourceString = "ITPDEBUG"_s;
        break;
    case MessageSource::PrivateClickMeasurement:
        sourceString = "PRIVATECLICKMEASUREMENT"_s;
        break;
    case MessageSource::PaymentRequest:
        sourceString = "PAYMENTREQUEST"_s;
        break;
    case MessageSource::Other:
        sourceString = "OTHER"_s;
        break;
    }

    String typeString;
    switch (type) {
    case MessageType::Log:
        // Default, no need to be more specific.
        break;
    case MessageType::Clear:
        typeString = "CLEAR"_s;
        break;
    case MessageType::Dir:
        typeString = "DIR"_s;
        break;
    case MessageType::DirXML:
        typeString = "DIRXML"_s;
        break;
    case MessageType::Table:
        typeString = "TABLE"_s;
        break;
    case MessageType::Trace:
        typeString = "TRACE"_s;
        break;
    case MessageType::StartGroup:
        typeString = "STARTGROUP"_s;
        break;
    case MessageType::StartGroupCollapsed:
        typeString = "STARTGROUPCOLLAPSED"_s;
        break;
    case MessageType::EndGroup:
        typeString = "ENDGROUP"_s;
        break;
    case MessageType::Assert:
        typeString = "ASSERT"_s;
        break;
    case MessageType::Timing:
        typeString = "TIMING"_s;
        break;
    case MessageType::Profile:
        typeString = "PROFILE"_s;
        break;
    case MessageType::ProfileEnd:
        typeString = "PROFILEEND"_s;
        break;
    case MessageType::Image:
        typeString = "IMAGE"_s;
        break;
    }

    String levelString;
    switch (level) {
    case MessageLevel::Log:
        // Default, no need to be more specific.
        if (type == MessageType::Log)
            levelString = "LOG"_s;
        break;
    case MessageLevel::Debug:
        levelString = "DEBUG"_s;
        break;
    case MessageLevel::Info:
        levelString = "INFO"_s;
        break;
    case MessageLevel::Warning:
        levelString = "WARN"_s;
        break;
    case MessageLevel::Error:
        levelString = "ERROR"_s;
        break;
    }

    builder.append("CONSOLE");
    if (!sourceString.isEmpty())
        builder.append(' ', sourceString);
    if (!typeString.isEmpty())
        builder.append(' ', typeString);
    if (!levelString.isEmpty())
        builder.append(' ', levelString);
}

void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber)
{
    StringBuilder builder;

    if (!url.isEmpty()) {
        appendURLAndPosition(builder, url, lineNumber, columnNumber);
        builder.append(": ");
    }

    appendMessagePrefix(builder, source, type, level);
    builder.append(' ', message);

    WTFLogAlways("%s", builder.toString().utf8().data());
}

void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    bool isTraceMessage = type == MessageType::Trace;
    size_t stackSize = isTraceMessage ? ScriptCallStack::maxCallStackSizeToCapture : 1;
    Ref<ScriptCallStack> callStack = createScriptCallStackForConsole(globalObject, stackSize);
    const ScriptCallFrame& lastCaller = callStack->at(0);

    StringBuilder builder;

    if (!lastCaller.sourceURL().isEmpty()) {
        appendURLAndPosition(builder, lastCaller.sourceURL(), lastCaller.lineNumber(), lastCaller.columnNumber());
        builder.append(": ");
    }

    appendMessagePrefix(builder, source, type, level);
    for (size_t i = 0; i < arguments->argumentCount(); ++i) {
        builder.append(' ');
        auto* globalObject = arguments->globalObject();
        auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
        builder.append(arguments->argumentAt(i).toWTFString(globalObject));
        scope.clearException();
    }

    WTFLogAlways("%s", builder.toString().utf8().data());

    if (isTraceMessage) {
        for (size_t i = 0; i < callStack->size(); ++i) {
            const ScriptCallFrame& callFrame = callStack->at(i);
            String functionName = callFrame.functionName();
            if (functionName.isEmpty())
                functionName = "(unknown)"_s;

            StringBuilder callFrameBuilder;
            callFrameBuilder.append(i, ": ", functionName, '(');
            appendURLAndPosition(callFrameBuilder, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber());
            callFrameBuilder.append(')');

            WTFLogAlways("%s", callFrameBuilder.toString().utf8().data());
        }
    }
}

void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments, ArgumentRequirement argumentRequirement)
{
    if (argumentRequirement == ArgumentRequired && !arguments->argumentCount())
        return;

    messageWithTypeAndLevel(type, level, globalObject, WTFMove(arguments));
}

void ConsoleClient::logWithLevel(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments, MessageLevel level)
{
    internalMessageWithTypeAndLevel(MessageType::Log, level, globalObject, WTFMove(arguments), ArgumentRequired);
}

void ConsoleClient::clear(JSGlobalObject* globalObject)
{
    internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, globalObject, ScriptArguments::create(globalObject, { }), ArgumentNotRequired);
}

void ConsoleClient::dir(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentRequired);
}

void ConsoleClient::dirXML(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentRequired);
}

void ConsoleClient::table(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentRequired);
}

void ConsoleClient::trace(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentNotRequired);
}

void ConsoleClient::assertion(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, globalObject, WTFMove(arguments), ArgumentNotRequired);
}

void ConsoleClient::group(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentNotRequired);
}

void ConsoleClient::groupCollapsed(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentNotRequired);
}

void ConsoleClient::groupEnd(JSGlobalObject* globalObject, Ref<ScriptArguments>&& arguments)
{
    internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, globalObject, WTFMove(arguments), ArgumentNotRequired);
}

} // namespace JSC
