/*
 * Copyright 2019 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/SkTypes.h"
#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkWriteBuffer.h"
#include "src/gpu/GrResourceProvider.h"
#include "tests/Test.h"

#include <memory>

class SkDescriptorTestHelper {
public:
    static void SetLength(SkDescriptor* desc, size_t length) { desc->fLength = length; }
    static void SetCount(SkDescriptor* desc, uint32_t count) { desc->fCount = count; }
};

DEF_TEST(Descriptor_empty, r) {
    const size_t size = sizeof(SkDescriptor);

    auto desc = SkDescriptor::Alloc(size);
    REPORTER_ASSERT(r, desc->isValid());
    REPORTER_ASSERT(r, desc->getLength() == size);
}

DEF_TEST(Descriptor_valid_simple, r) {
    const size_t size =
            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);

    auto desc = SkDescriptor::Alloc(size);
    SkScalerContextRec rec;
    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
    REPORTER_ASSERT(r, desc->isValid());
    REPORTER_ASSERT(r, desc->getLength() == size);

    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_valid_simple_extra_space, r) {
    const size_t extra_space = 100;
    const size_t size =
            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);

    auto desc = SkDescriptor::Alloc(size + extra_space);
    SkScalerContextRec rec;
    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
    REPORTER_ASSERT(r, desc->isValid());
    REPORTER_ASSERT(r, desc->getLength() == size);

    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_valid_more_tags, r) {
    const size_t effectSize = 16;
    const size_t testSize = 32;
    const size_t size = sizeof(SkDescriptor) + 3 * sizeof(SkDescriptor::Entry) +
                        sizeof(SkScalerContextRec) + effectSize + testSize;

    auto desc = SkDescriptor::Alloc(size);
    SkScalerContextRec rec;
    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
    desc->addEntry(kEffects_SkDescriptorTag, effectSize, nullptr);
    desc->addEntry(SkSetFourByteTag('t', 'e', 's', 't'), testSize, nullptr);
    REPORTER_ASSERT(r, desc->isValid());
    REPORTER_ASSERT(r, desc->getLength() == size);

    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_invalid_rec_size, r) {
    const size_t size =
            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) - 4;

    auto desc = SkDescriptor::Alloc(size);
    SkScalerContextRec rec;
    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec) - 4, &rec);
    REPORTER_ASSERT(r, desc->getLength() == size);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_invalid_length, r) {
    const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);
    const size_t effect_size = 1000;

    auto desc = SkDescriptor::Alloc(size);
    desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);

    SkDescriptorTestHelper::SetLength(desc.get(), size);
    REPORTER_ASSERT(r, !desc->isValid());

    SkDescriptorTestHelper::SetLength(desc.get(), size + effect_size);
    REPORTER_ASSERT(r, desc->isValid());
}

DEF_TEST(Descriptor_entry_too_big, r) {
    const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + 4;
    // Must be less than fLength, but big enough to be bigger then fLength when added.
    const size_t effect_size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);

    auto desc = SkDescriptor::Alloc(size);

    desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);

    SkDescriptorTestHelper::SetLength(desc.get(), size);
    SkDescriptorTestHelper::SetCount(desc.get(), 2);
    REPORTER_ASSERT(r, !desc->isValid());

    SkDescriptorTestHelper::SetLength(desc.get(), size);
    SkDescriptorTestHelper::SetCount(desc.get(), 1);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_entry_over_end, r) {
    auto desc = SkDescriptor::Alloc(36);

    // Make the start of the Entry be in the SkDescriptor, but the second half falls out side the
    // SkDescriptor. So: 12 (for descriptor) + 8 (for entry) + 12 (for entry length) = 32. An
    // An Entry is 8 bytes, so 4 bytes are < 36 and 4 bytes > 36.
    desc->addEntry(kEffects_SkDescriptorTag, 12, nullptr);

    SkDescriptorTestHelper::SetLength(desc.get(), 36);
    SkDescriptorTestHelper::SetCount(desc.get(), 2);
    REPORTER_ASSERT(r, !desc->isValid());
}

DEF_TEST(Descriptor_flatten_unflatten, r) {
    {
        SkBinaryWriteBuffer writer;
        auto desc = SkDescriptor::Alloc(sizeof(SkDescriptor));
        desc->computeChecksum();
        desc->flatten(writer);
        auto data = writer.snapshotAsData();
        SkReadBuffer reader{data->data(), data->size()};
        auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
        REPORTER_ASSERT(r, ad.has_value());
        REPORTER_ASSERT(r, ad->getDesc()->isValid());
    }

    {  // broken header
        SkBinaryWriteBuffer writer;
        writer.writeInt(0);  // fChecksum
        auto data = writer.snapshotAsData();
        SkReadBuffer reader{data->data(), data->size()};
        auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
        REPORTER_ASSERT(r, !ad.has_value());
    }

    {  // length too big
        SkBinaryWriteBuffer writer;
        // Simulate a broken header
        writer.writeInt(0);    // fChecksum
        writer.writeInt(4000); // fLength
        writer.writeInt(0);    // fCount
        auto data = writer.snapshotAsData();
        SkReadBuffer reader{data->data(), data->size()};
        auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
        REPORTER_ASSERT(r, !ad.has_value());
    }

    {  // length too small
        SkBinaryWriteBuffer writer;
        // Simulate a broken header
        writer.writeInt(0);    // fChecksum
        writer.writeInt(3);    // fLength
        writer.writeInt(0);    // fCount
        auto data = writer.snapshotAsData();
        SkReadBuffer reader{data->data(), data->size()};
        auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
        REPORTER_ASSERT(r, !ad.has_value());
    }

    {  // garbage in count
        SkBinaryWriteBuffer writer;
        // Simulate a broken header
        writer.writeInt(0);    // fChecksum
        writer.writeInt(20);   // fLength
        writer.writeInt(10);   // fCount
        writer.writeInt(0);
        writer.writeInt(0);
        auto data = writer.snapshotAsData();
        SkReadBuffer reader{data->data(), data->size()};
        auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
        REPORTER_ASSERT(r, !ad.has_value());
    }
}
