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