/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkEvent.h"

void SkEvent::initialize(const char* type, size_t typeLen,
                         SkEventSinkID targetID) {
    fType = nullptr;
    setType(type, typeLen);
    f32 = 0;
    fTargetID = targetID;
    fTargetProc = nullptr;
#ifdef SK_DEBUG
    fTime = 0;
    fNextEvent = nullptr;
#endif
}

SkEvent::SkEvent()
{
    initialize("", 0, 0);
}

SkEvent::SkEvent(const SkEvent& src)
{
    *this = src;
    if (((size_t) fType & 1) == 0)
        setType(src.fType);
}

SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID)
{
    initialize(type.c_str(), type.size(), targetID);
}

SkEvent::SkEvent(const char type[], SkEventSinkID targetID)
{
    SkASSERT(type);
    initialize(type, strlen(type), targetID);
}

SkEvent::~SkEvent()
{
    if (((size_t) fType & 1) == 0)
        sk_free((void*) fType);
}

static size_t makeCharArray(char* buffer, size_t compact)
{
    size_t bits = (size_t) compact >> 1;
    memcpy(buffer, &bits, sizeof(compact));
    buffer[sizeof(compact)] = 0;
    return strlen(buffer);
}

void SkEvent::getType(SkString* str) const
{
    if (str)
    {
        if ((size_t) fType & 1) // not a pointer
        {
            char chars[sizeof(size_t) + 1];
            size_t len = makeCharArray(chars, (size_t) fType);
            str->set(chars, len);
        }
        else
            str->set(fType);
    }
}

bool SkEvent::isType(const SkString& str) const
{
    return this->isType(str.c_str(), str.size());
}

bool SkEvent::isType(const char type[], size_t typeLen) const
{
    if (typeLen == 0)
        typeLen = strlen(type);
    if ((size_t) fType & 1) {   // not a pointer
        char chars[sizeof(size_t) + 1];
        size_t len = makeCharArray(chars, (size_t) fType);
        return len == typeLen && strncmp(chars, type, typeLen) == 0;
    }
    return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0;
}

void SkEvent::setType(const char type[], size_t typeLen)
{
    if (typeLen == 0)
        typeLen = strlen(type);
    if (typeLen <= sizeof(fType)) {
        size_t slot = 0;
        memcpy(&slot, type, typeLen);
        if (slot << 1 >> 1 != slot)
            goto useCharStar;
        slot <<= 1;
        slot |= 1;
        fType = (char*) slot;
    } else {
useCharStar:
        fType = (char*) sk_malloc_throw(typeLen + 1);
        SkASSERT(((size_t) fType & 1) == 0);
        memcpy(fType, type, typeLen);
        fType[typeLen] = 0;
    }
}

void SkEvent::setType(const SkString& type)
{
    setType(type.c_str());
}

////////////////////////////////////////////////////////////////////////////

#include "SkParse.h"

void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node)
{
    const char* name = dom.findAttr(node, "type");
    if (name)
        this->setType(name);

    const char* value;
    if ((value = dom.findAttr(node, "fast32")) != nullptr)
    {
        int32_t n;
        if (SkParse::FindS32(value, &n))
            this->setFast32(n);
    }

    for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node))
    {
        if (strcmp(dom.getName(node), "data"))
        {
            SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));)
            continue;
        }

        name = dom.findAttr(node, "name");
        if (name == nullptr)
        {
            SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");)
            continue;
        }

        if ((value = dom.findAttr(node, "s32")) != nullptr)
        {
            int32_t n;
            if (SkParse::FindS32(value, &n))
                this->setS32(name, n);
        }
        else if ((value = dom.findAttr(node, "scalar")) != nullptr)
        {
            SkScalar x;
            if (SkParse::FindScalar(value, &x))
                this->setScalar(name, x);
        }
        else if ((value = dom.findAttr(node, "string")) != nullptr)
            this->setString(name, value);
#ifdef SK_DEBUG
        else
        {
            SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name);
        }
#endif
    }
}

#ifdef SK_DEBUG

    #ifndef SkScalarToFloat
        #define SkScalarToFloat(x)  ((x) / 65536.f)
    #endif

    void SkEvent::dump(const char title[])
    {
        if (title)
            SkDebugf("%s ", title);

        SkString    etype;
        this->getType(&etype);
        SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32());

        const SkMetaData&   md = this->getMetaData();
        SkMetaData::Iter    iter(md);
        SkMetaData::Type    mtype;
        int                 count;
        const char*         name;

        while ((name = iter.next(&mtype, &count)) != nullptr)
        {
            SkASSERT(count > 0);

            SkDebugf(" <%s>=", name);
            switch (mtype) {
            case SkMetaData::kS32_Type:     // vector version???
                {
                    int32_t value;
                    md.findS32(name, &value);
                    SkDebugf("%d ", value);
                }
                break;
            case SkMetaData::kScalar_Type:
                {
                    const SkScalar* values = md.findScalars(name, &count, nullptr);
                    SkDebugf("%f", SkScalarToFloat(values[0]));
                    for (int i = 1; i < count; i++)
                        SkDebugf(", %f", SkScalarToFloat(values[i]));
                    SkDebugf(" ");
                }
                break;
            case SkMetaData::kString_Type:
                {
                    const char* value = md.findString(name);
                    SkASSERT(value);
                    SkDebugf("<%s> ", value);
                }
                break;
            case SkMetaData::kPtr_Type:     // vector version???
                {
                    void*   value;
                    md.findPtr(name, &value);
                    SkDebugf("%p ", value);
                }
                break;
            case SkMetaData::kBool_Type:    // vector version???
                {
                    bool    value;
                    md.findBool(name, &value);
                    SkDebugf("%s ", value ? "true" : "false");
                }
                break;
            default:
                SkDEBUGFAIL("unknown metadata type returned from iterator");
                break;
            }
        }
        SkDebugf("\n");
    }
#endif

///////////////////////////////////////////////////////////////////////////////////////

#ifdef SK_DEBUG
// #define SK_TRACE_EVENTSx
#endif

#ifdef SK_TRACE_EVENTS
    static void event_log(const char s[])
    {
        SkDEBUGF(("%s\n", s));
    }

    #define EVENT_LOG(s)        event_log(s)
    #define EVENT_LOGN(s, n)    do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0)
#else
    #define EVENT_LOG(s)
    #define EVENT_LOGN(s, n)
#endif

#include "SkMutex.h"
#include "SkTime.h"

class SkEvent_Globals {
public:
    SkEvent_Globals() {
        fEventQHead = nullptr;
        fEventQTail = nullptr;
        fDelayQHead = nullptr;
        SkDEBUGCODE(fEventCounter = 0;)
    }

    SkMutex     fEventMutex;
    SkEvent*    fEventQHead, *fEventQTail;
    SkEvent*    fDelayQHead;
    SkDEBUGCODE(int fEventCounter;)
};

static SkEvent_Globals& getGlobals() {
    // leak this, so we don't incure any shutdown perf hit
    static SkEvent_Globals* gGlobals = new SkEvent_Globals;
    return *gGlobals;
}

///////////////////////////////////////////////////////////////////////////////

void SkEvent::postDelay(SkMSec delay) {
    if (!fTargetID && !fTargetProc) {
        delete this;
        return;
    }

    if (delay) {
        this->postTime(GetMSecsSinceStartup() + delay);
        return;
    }

    SkEvent_Globals& globals = getGlobals();

    globals.fEventMutex.acquire();
    bool wasEmpty = SkEvent::Enqueue(this);
    globals.fEventMutex.release();

    // call outside of us holding the mutex
    if (wasEmpty) {
        SkEvent::SignalNonEmptyQueue();
    }
}

void SkEvent::postTime(SkMSec time) {
    if (!fTargetID && !fTargetProc) {
        delete this;
        return;
    }

    SkEvent_Globals& globals = getGlobals();

    globals.fEventMutex.acquire();
    SkMSec queueDelay = SkEvent::EnqueueTime(this, time);
    globals.fEventMutex.release();

    // call outside of us holding the mutex
    if ((int32_t)queueDelay != ~0) {
        SkEvent::SignalQueueTimer(queueDelay);
    }
}

bool SkEvent::Enqueue(SkEvent* evt) {
    SkEvent_Globals& globals = getGlobals();
    //  gEventMutex acquired by caller

    SkASSERT(evt);

    bool wasEmpty = globals.fEventQHead == nullptr;

    if (globals.fEventQTail)
        globals.fEventQTail->fNextEvent = evt;
    globals.fEventQTail = evt;
    if (globals.fEventQHead == nullptr)
        globals.fEventQHead = evt;
    evt->fNextEvent = nullptr;

    SkDEBUGCODE(++globals.fEventCounter);

    return wasEmpty;
}

SkEvent* SkEvent::Dequeue() {
    SkEvent_Globals& globals = getGlobals();
    globals.fEventMutex.acquire();

    SkEvent* evt = globals.fEventQHead;
    if (evt) {
        SkDEBUGCODE(--globals.fEventCounter);

        globals.fEventQHead = evt->fNextEvent;
        if (globals.fEventQHead == nullptr) {
            globals.fEventQTail = nullptr;
        }
    }
    globals.fEventMutex.release();

    return evt;
}

bool SkEvent::QHasEvents() {
    SkEvent_Globals& globals = getGlobals();

    // this is not thread accurate, need a semaphore for that
    return globals.fEventQHead != nullptr;
}

#ifdef SK_TRACE_EVENTS
    static int gDelayDepth;
#endif

SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) {
    SkEvent_Globals& globals = getGlobals();
    //  gEventMutex acquired by caller

    SkEvent* curr = globals.fDelayQHead;
    SkEvent* prev = nullptr;

    while (curr) {
        if (SkMSec_LT(time, curr->fTime)) {
            break;
        }
        prev = curr;
        curr = curr->fNextEvent;
    }

    evt->fTime = time;
    evt->fNextEvent = curr;
    if (prev == nullptr) {
        globals.fDelayQHead = evt;
    } else {
        prev->fNextEvent = evt;
    }

    SkMSec delay = globals.fDelayQHead->fTime - GetMSecsSinceStartup();
    if ((int32_t)delay <= 0) {
        delay = 1;
    }
    return delay;
}

///////////////////////////////////////////////////////////////////////////////

#include "SkEventSink.h"

bool SkEvent::ProcessEvent() {
    std::unique_ptr<SkEvent> evt(SkEvent::Dequeue());
    bool                     again = false;

    EVENT_LOGN("ProcessEvent", (int32_t)evt);

    if (evt) {
        (void)SkEventSink::DoEvent(*evt);
        again = SkEvent::QHasEvents();
    }
    return again;
}

void SkEvent::ServiceQueueTimer()
{
    SkEvent_Globals& globals = getGlobals();

    globals.fEventMutex.acquire();

    bool        wasEmpty = false;
    SkMSec      now = GetMSecsSinceStartup();
    SkEvent*    evt = globals.fDelayQHead;

    while (evt)
    {
        if (SkMSec_LT(now, evt->fTime))
            break;

#ifdef SK_TRACE_EVENTS
        --gDelayDepth;
        SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth);
        const char* idStr = evt->findString("id");
        if (idStr)
            SkDebugf(" (%s)", idStr);
        SkDebugf("\n");
#endif

        SkEvent* next = evt->fNextEvent;
        if (SkEvent::Enqueue(evt))
            wasEmpty = true;
        evt = next;
    }
    globals.fDelayQHead = evt;

    SkMSec time = evt ? evt->fTime - now : 0;

    globals.fEventMutex.release();

    if (wasEmpty)
        SkEvent::SignalNonEmptyQueue();

    SkEvent::SignalQueueTimer(time);
}

int SkEvent::CountEventsOnQueue() {
    SkEvent_Globals& globals = getGlobals();
    globals.fEventMutex.acquire();

    int count = 0;
    const SkEvent* evt = globals.fEventQHead;
    while (evt) {
        count += 1;
        evt = evt->fNextEvent;
    }
    globals.fEventMutex.release();

    return count;
}

SkMSec SkEvent::GetMSecsSinceStartup() {
    static const double kEpoch = SkTime::GetMSecs();
    return static_cast<SkMSec>(SkTime::GetMSecs() - kEpoch);
}

///////////////////////////////////////////////////////////////////////////////

void SkEvent::Init() {}

void SkEvent::Term() {
    SkEvent_Globals& globals = getGlobals();

    SkEvent* evt = globals.fEventQHead;
    while (evt) {
        SkEvent* next = evt->fNextEvent;
        delete evt;
        evt = next;
    }

    evt = globals.fDelayQHead;
    while (evt) {
        SkEvent* next = evt->fNextEvent;
        delete evt;
        evt = next;
    }
}
