/*
 * Copyright (C) 2013 Google 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 AND ITS 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 APPLE OR ITS 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 "sky/engine/config.h"
#include "sky/engine/wtf/InstanceCounter.h"

#include "sky/engine/wtf/HashMap.h"
#include "sky/engine/wtf/StdLibExtras.h"
#include "sky/engine/wtf/ThreadingPrimitives.h"
#include "sky/engine/wtf/text/StringBuilder.h"
#include "sky/engine/wtf/text/StringHash.h"
#include "sky/engine/wtf/text/WTFString.h"

namespace WTF {

#if ENABLE(INSTANCE_COUNTER) || ENABLE(GC_PROFILING)

#if COMPILER(CLANG)
const size_t extractNameFunctionPrefixLength = sizeof("const char *WTF::extractNameFunction() [T = ") - 1;
const size_t extractNameFunctionPostfixLength = sizeof("]") - 1;
#elif COMPILER(GCC)
const size_t extractNameFunctionPrefixLength = sizeof("const char* WTF::extractNameFunction() [with T = ") - 1;
const size_t extractNameFunctionPostfixLength = sizeof("]") - 1;
#else
#warning "Extracting typename is supported only in compiler GCC, CLANG and MSVC at this moment"
#endif

// This function is used to stringify a typename T without using RTTI.
// The result of extractNameFunction<T>() is given as |funcName|. |extractTypeNameFromFunctionName| then extracts a typename string from |funcName|.
String extractTypeNameFromFunctionName(const char* funcName)
{
#if COMPILER(CLANG) || COMPILER(GCC)
    size_t funcNameLength = strlen(funcName);
    ASSERT(funcNameLength > extractNameFunctionPrefixLength + extractNameFunctionPostfixLength);

    const char* funcNameWithoutPrefix = funcName + extractNameFunctionPrefixLength;
    return String(funcNameWithoutPrefix, funcNameLength - extractNameFunctionPrefixLength - extractNameFunctionPostfixLength);
#else
    return String("unknown");
#endif
}

class InstanceCounter {
public:
    void incrementInstanceCount(const String& instanceName, void* ptr);
    void decrementInstanceCount(const String& instanceName, void* ptr);
    String dump();

    static InstanceCounter* instance()
    {
        DEFINE_STATIC_LOCAL(InstanceCounter, self, ());
        return &self;
    }

private:
    InstanceCounter() { }

    Mutex m_mutex;
    HashMap<String, int> m_counterMap;
};

void incrementInstanceCount(const char* extractNameFunctionName, void* ptr)
{
    String instanceName = extractTypeNameFromFunctionName(extractNameFunctionName);
    InstanceCounter::instance()->incrementInstanceCount(instanceName, ptr);
}

void decrementInstanceCount(const char* extractNameFunctionName, void* ptr)
{
    String instanceName = extractTypeNameFromFunctionName(extractNameFunctionName);
    InstanceCounter::instance()->decrementInstanceCount(instanceName, ptr);
}

String dumpRefCountedInstanceCounts()
{
    return InstanceCounter::instance()->dump();
}

void InstanceCounter::incrementInstanceCount(const String& instanceName, void* ptr)
{
    MutexLocker locker(m_mutex);
    HashMap<String, int>::AddResult result = m_counterMap.add(instanceName, 1);
    if (!result.isNewEntry)
        ++(result.storedValue->value);
}

void InstanceCounter::decrementInstanceCount(const String& instanceName, void* ptr)
{
    MutexLocker locker(m_mutex);
    HashMap<String, int>::iterator it = m_counterMap.find(instanceName);
    ASSERT(it != m_counterMap.end());

    --(it->value);
    if (!it->value)
        m_counterMap.remove(it);
}

String InstanceCounter::dump()
{
    MutexLocker locker(m_mutex);

    StringBuilder builder;

    builder.append("{");
    HashMap<String, int>::iterator it = m_counterMap.begin();
    HashMap<String, int>::iterator itEnd = m_counterMap.end();
    for (; it != itEnd; ++it) {
        if (it != m_counterMap.begin())
            builder.append(",");
        builder.append("\"");
        builder.append(it->key);
        builder.append("\": ");
        builder.append(String::number(it->value));
    }
    builder.append("}");

    return builder.toString();
}

#else

String dumpRefCountedInstanceCounts()
{
    return String("{}");
}

#endif // ENABLE(INSTANCE_COUNTER) || ENABLE(GC_PROFILING)

} // namespace WTF
