/*
 * Copyright (C) 2015, 2017 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. 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 INC. 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 "config.h"
#include "ResourceUsageOverlay.h"

#if ENABLE(RESOURCE_USAGE)

#include <CoreText/CoreText.h>

#include "CommonVM.h"
#include "JSDOMWindow.h"
#include "PlatformCALayer.h"
#include "ResourceUsageThread.h"
#include <CoreGraphics/CGContext.h>
#include <QuartzCore/CALayer.h>
#include <QuartzCore/CATransaction.h>
#include <wtf/MainThread.h>
#include <wtf/MathExtras.h>
#include <wtf/MemoryFootprint.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringConcatenateNumbers.h>

using WebCore::ResourceUsageOverlay;
@interface WebOverlayLayer : CALayer {
    ResourceUsageOverlay* m_overlay;
}
@end

@implementation WebOverlayLayer

- (WebOverlayLayer *)initWithResourceUsageOverlay:(ResourceUsageOverlay *)overlay
{
    self = [super init];
    if (!self)
        return nil;
    m_overlay = overlay;
    return self;
}

- (void)drawInContext:(CGContextRef)context
{
    m_overlay->platformDraw(context);
}

@end

namespace WebCore {

template<typename T, size_t size = 70>
class RingBuffer {
public:
    RingBuffer()
    {
        m_data.fill(0);
    }

    void append(T v)
    {
        m_data[m_current] = WTFMove(v);
        incrementIndex(m_current);
    }

    T& last()
    {
        unsigned index = m_current;
        decrementIndex(index);
        return m_data[index];
    }

    void forEach(const WTF::Function<void(T)>& apply) const
    {
        unsigned i = m_current;
        for (unsigned visited = 0; visited < size; ++visited) {
            apply(m_data[i]);
            incrementIndex(i);
        }
    }

private:
    static void incrementIndex(unsigned& index)
    {
        if (++index == size)
            index = 0;
    }

    static void decrementIndex(unsigned& index)
    {
        if (index)
            --index;
        else
            index = size - 1;
    }

    std::array<T, size> m_data;
    unsigned m_current { 0 };
};

static CGColorRef createColor(float r, float g, float b, float a)
{
    static CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
    CGFloat components[4] = { r, g, b, a };
    return CGColorCreate(colorSpace, components);
}

struct HistoricMemoryCategoryInfo {
    HistoricMemoryCategoryInfo() { } // Needed for std::array.

    HistoricMemoryCategoryInfo(unsigned category, RGBA32 rgba, String name, bool subcategory = false)
        : name(WTFMove(name))
        , isSubcategory(subcategory)
        , type(category)
    {
        float r, g, b, a;
        Color(rgba).getRGBA(r, g, b, a);
        color = adoptCF(createColor(r, g, b, a));
    }

    String name;
    RetainPtr<CGColorRef> color;
    RingBuffer<size_t> dirtySize;
    RingBuffer<size_t> reclaimableSize;
    RingBuffer<size_t> externalSize;
    bool isSubcategory { false };
    unsigned type { MemoryCategory::NumberOfCategories };
};

struct HistoricResourceUsageData {
    HistoricResourceUsageData();

    RingBuffer<float> cpu;
    RingBuffer<size_t> totalDirtySize;
    RingBuffer<size_t> totalExternalSize;
    RingBuffer<size_t> gcHeapSize;
    std::array<HistoricMemoryCategoryInfo, MemoryCategory::NumberOfCategories> categories;
    MonotonicTime timeOfNextEdenCollection { MonotonicTime::nan() };
    MonotonicTime timeOfNextFullCollection { MonotonicTime::nan() };
};

HistoricResourceUsageData::HistoricResourceUsageData()
{
    // VM tag categories.
    categories[MemoryCategory::JSJIT] = HistoricMemoryCategoryInfo(MemoryCategory::JSJIT, 0xFFFF60FF, "JS JIT");
    categories[MemoryCategory::WebAssembly] = HistoricMemoryCategoryInfo(MemoryCategory::WebAssembly, 0xFF654FF0, "WebAssembly");
    categories[MemoryCategory::Images] = HistoricMemoryCategoryInfo(MemoryCategory::Images, 0xFFFFFF00, "Images");
    categories[MemoryCategory::Layers] = HistoricMemoryCategoryInfo(MemoryCategory::Layers, 0xFF00FFFF, "Layers");
    categories[MemoryCategory::LibcMalloc] = HistoricMemoryCategoryInfo(MemoryCategory::LibcMalloc, 0xFF00FF00, "libc malloc");
    categories[MemoryCategory::bmalloc] = HistoricMemoryCategoryInfo(MemoryCategory::bmalloc, 0xFFFF6060, "bmalloc");
    categories[MemoryCategory::Other] = HistoricMemoryCategoryInfo(MemoryCategory::Other, 0xFFC0FF00, "Other");

    // Sub categories (e.g breakdown of bmalloc tag.)
    categories[MemoryCategory::GCHeap] = HistoricMemoryCategoryInfo(MemoryCategory::GCHeap, 0xFFA0A0FF, "GC heap", true);
    categories[MemoryCategory::GCOwned] = HistoricMemoryCategoryInfo(MemoryCategory::GCOwned, 0xFFFFC060, "GC owned", true);

#ifndef NDEBUG
    // Ensure this aligns with ResourceUsageData's category order.
    ResourceUsageData d;
    ASSERT(categories.size() == d.categories.size());
    for (size_t i = 0; i < categories.size(); ++i)
        ASSERT(categories[i].type == d.categories[i].type);
#endif
}

static HistoricResourceUsageData& historicUsageData()
{
    static NeverDestroyed<HistoricResourceUsageData> data;
    return data;
}

static void appendDataToHistory(const ResourceUsageData& data)
{
    ASSERT(isMainThread());

    auto& historicData = historicUsageData();
    historicData.cpu.append(data.cpu);
    historicData.totalDirtySize.append(data.totalDirtySize);
    historicData.totalExternalSize.append(data.totalExternalSize);
    for (auto& category : historicData.categories) {
        category.dirtySize.append(data.categories[category.type].dirtySize);
        category.reclaimableSize.append(data.categories[category.type].reclaimableSize);
        category.externalSize.append(data.categories[category.type].externalSize);
    }
    historicData.timeOfNextEdenCollection = data.timeOfNextEdenCollection;
    historicData.timeOfNextFullCollection = data.timeOfNextFullCollection;

    // FIXME: Find a way to add this to ResourceUsageData and calculate it on the resource usage sampler thread.
    {
        JSC::VM* vm = &commonVM();
        JSC::JSLockHolder lock(vm);
        historicData.gcHeapSize.append(vm->heap.size() - vm->heap.extraMemorySize());
    }
}

void ResourceUsageOverlay::platformInitialize()
{
    m_layer = adoptNS([[WebOverlayLayer alloc] initWithResourceUsageOverlay:this]);

    m_containerLayer = adoptNS([[CALayer alloc] init]);
    [m_containerLayer.get() addSublayer:m_layer.get()];

    [m_containerLayer.get() setAnchorPoint:CGPointZero];
    [m_containerLayer.get() setBounds:CGRectMake(0, 0, normalWidth, normalHeight)];

    [m_layer.get() setAnchorPoint:CGPointZero];
    [m_layer.get() setContentsScale:2.0];
    [m_layer.get() setBackgroundColor:adoptCF(createColor(0, 0, 0, 0.8)).get()];
    [m_layer.get() setBounds:CGRectMake(0, 0, normalWidth, normalHeight)];

    overlay().layer().setContentsToPlatformLayer(m_layer.get(), GraphicsLayer::ContentsLayerPurpose::None);

    ResourceUsageThread::addObserver(this, All, [this] (const ResourceUsageData& data) {
        appendDataToHistory(data);

        // FIXME: It shouldn't be necessary to update the bounds on every single thread loop iteration,
        // but something is causing them to become 0x0.
        [CATransaction begin];
        CALayer *containerLayer = [m_layer superlayer];
        CGRect rect = CGRectMake(0, 0, ResourceUsageOverlay::normalWidth, ResourceUsageOverlay::normalHeight);
        [m_layer setBounds:rect];
        [containerLayer setBounds:rect];
        [m_layer setNeedsDisplay];
        [CATransaction commit];
    });
}

void ResourceUsageOverlay::platformDestroy()
{
    ResourceUsageThread::removeObserver(this);
}

static void showText(CGContextRef context, float x, float y, CGColorRef color, const String& text)
{
    CGContextSaveGState(context);

    CGContextSetTextDrawingMode(context, kCGTextFill);
    CGContextSetFillColorWithColor(context, color);

    auto matrix = CGAffineTransformMakeScale(1, -1);
#if PLATFORM(IOS_FAMILY)
    CFStringRef fontName = CFSTR("Courier");
    CGFloat fontSize = 10;
#else
    CFStringRef fontName = CFSTR("Menlo");
    CGFloat fontSize = 11;
#endif
    auto font = adoptCF(CTFontCreateWithName(fontName, fontSize, &matrix));
    CFTypeRef keys[] = { kCTFontAttributeName, kCTForegroundColorFromContextAttributeName };
    CFTypeRef values[] = { font.get(), kCFBooleanTrue };
    auto attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
    CString cstr = text.ascii();
    auto string = adoptCF(CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(cstr.data()), cstr.length(), kCFStringEncodingASCII, false, kCFAllocatorNull));
    auto attributedString = adoptCF(CFAttributedStringCreate(kCFAllocatorDefault, string.get(), attributes.get()));
    auto line = adoptCF(CTLineCreateWithAttributedString(attributedString.get()));
    CGContextSetTextPosition(context, x, y);
    CTLineDraw(line.get(), context);

    CGContextRestoreGState(context);
}

static void drawGraphLabel(CGContextRef context, float x, float y, const String& text)
{
    static CGColorRef black = createColor(0, 0, 0, 1);
    showText(context, x + 5, y - 3, black, text);
    static CGColorRef white = createColor(1, 1, 1, 1);
    showText(context, x + 4, y - 4, white, text);
}

static void drawCpuHistory(CGContextRef context, float x1, float y1, float y2, RingBuffer<float>& history)
{
    static CGColorRef cpuColor = createColor(0, 1, 0, 1);

    CGContextSetStrokeColorWithColor(context, cpuColor);
    CGContextSetLineWidth(context, 1);

    int i = 0;

    history.forEach([&](float c) {
        float cpu = c / 100;
        float yScale = y2 - y1;

        CGContextBeginPath(context);
        CGContextMoveToPoint(context, x1 + i, y2);
        CGContextAddLineToPoint(context, x1 + i, y2 - (yScale * cpu));
        CGContextStrokePath(context);
        i++;
    });

    drawGraphLabel(context, x1, y2, "CPU");
}

static void drawGCHistory(CGContextRef context, float x1, float y1, float y2, RingBuffer<size_t>& sizeHistory, RingBuffer<size_t>& capacityHistory)
{
    float yScale = y2 - y1;

    size_t peak = 0;
    capacityHistory.forEach([&](size_t m) {
        if (m > peak)
            peak = m;
    });

    CGContextSetLineWidth(context, 1);

    static CGColorRef capacityColor = createColor(1, 0, 0.3, 1);
    CGContextSetStrokeColorWithColor(context, capacityColor);

    size_t i = 0;

    capacityHistory.forEach([&](size_t m) {
        float mem = (float)m / (float)peak;
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, x1 + i, y2);
        CGContextAddLineToPoint(context, x1 + i, y2 - (yScale * mem));
        CGContextStrokePath(context);
        i++;
    });

    static CGColorRef sizeColor = createColor(0.6, 0.5, 0.9, 1);
    CGContextSetStrokeColorWithColor(context, sizeColor);

    i = 0;

    sizeHistory.forEach([&](size_t m) {
        float mem = (float)m / (float)peak;
        CGContextBeginPath(context);
        CGContextMoveToPoint(context, x1 + i, y2);
        CGContextAddLineToPoint(context, x1 + i, y2 - (yScale * mem));
        CGContextStrokePath(context);
        i++;
    });

    drawGraphLabel(context, x1, y2, "GC");
}

static void drawMemHistory(CGContextRef context, float x1, float y1, float y2, HistoricResourceUsageData& data)
{
    float yScale = y2 - y1;

    size_t peak = 0;
    data.totalDirtySize.forEach([&](size_t m) {
        if (m > peak)
            peak = m;
    });

    CGContextSetLineWidth(context, 1);

    struct ColorAndSize {
        CGColorRef color;
        size_t size;
    };

    std::array<std::array<ColorAndSize, MemoryCategory::NumberOfCategories>, 70> columns;

    for (auto& category : data.categories) {
        unsigned x = 0;
        category.dirtySize.forEach([&](size_t m) {
            columns[x][category.type] = { category.color.get(), m };
            ++x;
        });
    }

    unsigned i = 0;
    for (auto& column : columns) {
        float currentY2 = y2;
        for (auto& colorAndSize : column) {
            float chunk = (float)colorAndSize.size / (float)peak;
            float nextY2 = currentY2 - (yScale * chunk);
            CGContextBeginPath(context);
            CGContextMoveToPoint(context, x1 + i, currentY2);
            CGContextAddLineToPoint(context, x1 + i, nextY2);
            CGContextSetStrokeColorWithColor(context, colorAndSize.color);
            CGContextStrokePath(context);
            currentY2 = nextY2;
        }
        ++i;
    }

    drawGraphLabel(context, x1, y2, "Mem");
}

static const float fullCircleInRadians = piFloat * 2;

static void drawSlice(CGContextRef context, FloatPoint center, float& angle, float radius, size_t sliceSize, size_t totalSize, CGColorRef color)
{
    float part = (float)sliceSize / (float)totalSize;

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, center.x(), center.y());
    CGContextAddArc(context, center.x(), center.y(), radius, angle, angle + part * fullCircleInRadians, false);
    CGContextSetFillColorWithColor(context, color);
    CGContextFillPath(context);
    angle += part * fullCircleInRadians;
}

static void drawMemoryPie(CGContextRef context, FloatRect& rect, HistoricResourceUsageData& data)
{
    float radius = rect.width() / 2;
    FloatPoint center = rect.center();
    size_t totalDirty = data.totalDirtySize.last();

    float angle = 0;
    for (auto& category : data.categories)
        drawSlice(context, center, angle, radius, category.dirtySize.last(), totalDirty, category.color.get());
}

static String formatByteNumber(size_t number)
{
    if (number >= 1024 * 1048576)
        return makeString(FormattedNumber::fixedWidth(number / (1024. * 1048576), 3), " GB");
    if (number >= 1048576)
        return makeString(FormattedNumber::fixedWidth(number / 1048576., 2), " MB");
    if (number >= 1024)
        return makeString(FormattedNumber::fixedWidth(number / 1024, 1), " kB");
    return String::number(number);
}

static String gcTimerString(MonotonicTime timerFireDate, MonotonicTime now)
{
    if (std::isnan(timerFireDate))
        return "[not scheduled]"_s;
    return String::numberToStringFixedPrecision((timerFireDate - now).seconds());
}

void ResourceUsageOverlay::platformDraw(CGContextRef context)
{
    auto& data = historicUsageData();

    if (![m_layer.get() contentsAreFlipped]) {
        CGContextScaleCTM(context, 1, -1);
        CGContextTranslateCTM(context, 0, -normalHeight);
    }

    CGContextSetShouldAntialias(context, false);
    CGContextSetShouldSmoothFonts(context, false);

    CGRect viewBounds = m_overlay->bounds();
    CGContextClearRect(context, viewBounds);

    static CGColorRef colorForLabels = createColor(0.9, 0.9, 0.9, 1);
    showText(context, 10, 20, colorForLabels, makeString("        CPU: ", FormattedNumber::fixedPrecision(data.cpu.last(), 6, KeepTrailingZeros)));
    showText(context, 10, 30, colorForLabels, "  Footprint: " + formatByteNumber(memoryFootprint()));
    showText(context, 10, 40, colorForLabels, "   External: " + formatByteNumber(data.totalExternalSize.last()));

    float y = 55;
    for (auto& category : data.categories) {
        size_t dirty = category.dirtySize.last();
        size_t reclaimable = category.reclaimableSize.last();
        size_t external = category.externalSize.last();
        
        String label = makeString(pad(' ', 11, category.name), ": ", formatByteNumber(dirty));
        if (external)
            label = label + makeString(" + ", formatByteNumber(external));
        if (reclaimable)
            label = label + makeString(" [", formatByteNumber(reclaimable), ']');

        // FIXME: Show size/capacity of GC heap.
        showText(context, 10, y, category.color.get(), label);
        y += 10;
    }
    y -= 5;

    MonotonicTime now = MonotonicTime::now();
    showText(context, 10, y + 10, colorForLabels, "    Eden GC: " + gcTimerString(data.timeOfNextEdenCollection, now));
    showText(context, 10, y + 20, colorForLabels, "    Full GC: " + gcTimerString(data.timeOfNextFullCollection, now));

    drawCpuHistory(context, viewBounds.size.width - 70, 0, viewBounds.size.height, data.cpu);
    drawGCHistory(context, viewBounds.size.width - 140, 0, viewBounds.size.height, data.gcHeapSize, data.categories[MemoryCategory::GCHeap].dirtySize);
    drawMemHistory(context, viewBounds.size.width - 210, 0, viewBounds.size.height, data);

    FloatRect pieRect(viewBounds.size.width - 330, 0, 100, viewBounds.size.height);
    drawMemoryPie(context, pieRect, data);
}

}

#endif // ENABLE(RESOURCE_USAGE)
