/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkRefCnt.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/base/SkTArray.h"
#include "src/core/SkMessageBus.h"
#include "tests/Test.h"

#include <cstdint>
#include <utility>

namespace {

struct TestMessage {
    TestMessage(int i, float f) : x(i), y(f) {}

    int x;
    float y;
};

static inline bool SkShouldPostMessageToBus(const TestMessage&, uint32_t) {
    return true;
}

}  // namespace

DECLARE_SKMESSAGEBUS_MESSAGE(TestMessage, uint32_t, true)

DEF_TEST(MessageBus, r) {
    using TestMessageBus = SkMessageBus<TestMessage, uint32_t>;
    // Register two inboxes to receive all TestMessages.
    TestMessageBus::Inbox inbox1(0), inbox2(0);

    // Send two messages.
    const TestMessage m1 = { 5, 4.2f };
    const TestMessage m2 = { 6, 4.3f };
    TestMessageBus::Post(std::move(m1));
    TestMessageBus::Post(std::move(m2));

    // Make sure we got two.
    SkTArray<TestMessage> messages;
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 2 == messages.size());
    REPORTER_ASSERT(r, 5 == messages[0].x);
    REPORTER_ASSERT(r, 6 == messages[1].x);

    // Send another; check we get just that one.
    const TestMessage m3 = { 1, 0.3f };
    TestMessageBus::Post(m3);
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 1 == messages.size());
    REPORTER_ASSERT(r, 1 == messages[0].x);

    // Nothing was sent since the last read.
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 0 == messages.size());

    // Over all this time, inbox2 should have piled up 3 messages.
    inbox2.poll(&messages);
    REPORTER_ASSERT(r, 3 == messages.size());
    REPORTER_ASSERT(r, 5 == messages[0].x);
    REPORTER_ASSERT(r, 6 == messages[1].x);
    REPORTER_ASSERT(r, 1 == messages[2].x);
}

namespace {

struct TestMessageRefCnt : public SkRefCnt {
    TestMessageRefCnt(int i, float f) : x(i), y(f) {}

    int x;
    float y;
};

static inline bool SkShouldPostMessageToBus(const sk_sp<TestMessageRefCnt>&, uint32_t) {
    return true;
}

}  // namespace

DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<TestMessageRefCnt>, uint32_t, false)

DEF_TEST(MessageBusSp, r) {
    // Register two inboxes to receive all TestMessages.
    using TestMessageBus = SkMessageBus<sk_sp<TestMessageRefCnt>, uint32_t, false>;
    TestMessageBus::Inbox inbox1(0);

    // Send two messages.
    auto m1 = sk_make_sp<TestMessageRefCnt>(5, 4.2f);
    auto m2 = sk_make_sp<TestMessageRefCnt>(6, 4.3f);
    TestMessageBus::Post(std::move(m1));
    TestMessageBus::Post(std::move(m2));

    // Make sure we got two.
    SkTArray<sk_sp<TestMessageRefCnt>> messages;
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 2 == messages.size());
    REPORTER_ASSERT(r, messages[0]->unique());
    REPORTER_ASSERT(r, messages[1]->unique());
    REPORTER_ASSERT(r, 5 == messages[0]->x);
    REPORTER_ASSERT(r, 6 == messages[1]->x);

    // Send another; check we get just that one.
    auto m3 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
    TestMessageBus::Post(std::move(m3));
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 1 == messages.size());
    REPORTER_ASSERT(r, messages[0]->unique());
    REPORTER_ASSERT(r, 1 == messages[0]->x);

    // Send another without std::move(), it should trigger SkASSERT().
    // auto m4 = sk_make_sp<TestMessageRefCnt>(1, 0.3f);
    // TestMessageBus::Post(m4);

    // Nothing was sent since the last read.
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, 0 == messages.size());
}

namespace {

struct AddressedMessage {
    GrDirectContext::DirectContextID fInboxID;
};

static inline bool SkShouldPostMessageToBus(const AddressedMessage& msg,
                                            GrDirectContext::DirectContextID msgBusUniqueID) {
    SkASSERT(msgBusUniqueID.isValid());
    if (!msg.fInboxID.isValid()) {
        return true;
    }
    return msgBusUniqueID == msg.fInboxID;
}

}  // namespace

DECLARE_SKMESSAGEBUS_MESSAGE(AddressedMessage, GrDirectContext::DirectContextID, true)

DEF_TEST(MessageBus_SkShouldPostMessageToBus, r) {
    using ID = GrDirectContext::DirectContextID;
    using AddressedMessageBus = SkMessageBus<AddressedMessage, ID>;

    ID idInvalid;
    ID id1 = ID::Next(),
       id2 = ID::Next(),
       id3 = ID::Next();

    AddressedMessageBus::Inbox inbox1(id1), inbox2(id2);

    AddressedMessageBus::Post({idInvalid});  // Should go to both
    AddressedMessageBus::Post({id1});        // Should go to inbox1
    AddressedMessageBus::Post({id2});        // Should go to inbox2
    AddressedMessageBus::Post({id3});        // Should go nowhere

    SkTArray<AddressedMessage> messages;
    inbox1.poll(&messages);
    REPORTER_ASSERT(r, messages.size() == 2);
    if (messages.size() == 2) {
        REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
        REPORTER_ASSERT(r, messages[1].fInboxID == id1);
    }
    inbox2.poll(&messages);
    REPORTER_ASSERT(r, messages.size() == 2);
    if (messages.size() == 2) {
        REPORTER_ASSERT(r, !messages[0].fInboxID.isValid());
        REPORTER_ASSERT(r, messages[1].fInboxID == id2);
    }
}

// Multithreaded tests tbd.
