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

#include "include/core/SkMesh.h"
#include "include/private/SkTArray.h"

#include "fuzz/Fuzz.h"

#include <array>

using namespace skia_private;

template <typename T>
T extract(SkSpan<const uint8_t>& data) {
    T result = 0;
    size_t bytesToCopy = std::min(sizeof(T), data.size());
    if (bytesToCopy > 0) {
        memcpy(&result, &data.front(), bytesToCopy);
        data = data.subspan(bytesToCopy);
    }
    return result;
}

void FuzzSkMeshSpecification(const uint8_t *fuzzData, size_t fuzzSize) {
    using Attribute = SkMeshSpecification::Attribute;
    using Varying = SkMeshSpecification::Varying;

    SkSpan<const uint8_t> data(fuzzData, fuzzSize);
    STArray<SkMeshSpecification::kMaxAttributes, Attribute> attributes;
    STArray<SkMeshSpecification::kMaxVaryings,   Varying>   varyings;
    size_t vertexStride;
    SkString vs, fs;

    auto fuzzByteToASCII = [&](uint8_t c, SkString* str) -> bool {
        // Most control characters (including \0) and all high ASCII are treated as stop bytes.
        if ((c >= 32 && c <= 127) || c == '\r' || c == '\n' || c == '\t') {
            char ascii = c;
            str->append(&ascii, 1);
            return true;
        }
        return false;
    };

    auto fuzzByteToSkSL = [&](uint8_t c, SkString* str) -> bool {
        // In the 0x00 - 0x80 range, treat characters as ASCII.
        if (c < 128) {
            return fuzzByteToASCII(c, str);
        }
        c -= 128;

        // Dedicate a few bytes to injecting our attribute and varying names.
        if (c < SkMeshSpecification::kMaxAttributes) {
            if (!attributes.empty()) {
                str->append(attributes[c % attributes.size()].name);
            }
            return true;
        }
        c -= SkMeshSpecification::kMaxAttributes;

        if (c < SkMeshSpecification::kMaxVaryings) {
            if (!varyings.empty()) {
                str->append(varyings[c % varyings.size()].name);
            }
            return true;
        }
        c -= SkMeshSpecification::kMaxVaryings;

        // Replace the remaining high-ASCII bytes with valid SkSL operators and keywords in order to
        // improve our chances of generating a program. (We omit single-character operators since
        // single-byte versions of those already exist in the low-ASCII space.)
        static constexpr auto kSkSLData = std::to_array<std::string_view>({
                " true ",
                " false ",
                " if ",
                " else ",
                " for ",
                " while ",
                " do ",
                " switch ",
                " case ",
                " default ",
                " break ",
                " continue ",
                " discard ",
                " return ",
                " in ",
                " out ",
                " inout ",
                " uniform ",
                " const ",
                " flat ",
                " noperspective ",
                " inline ",
                " noinline ",
                " $pure ",
                " readonly ",
                " writeonly ",
                " buffer ",
                " struct ",
                " layout ",
                " highp ",
                " mediump ",
                " lowp ",
                " $es3 ",
                " $export ",
                " workgroup ",
                " << ",
                " >> ",
                " && ",
                " || ",
                " ^^ ",
                " == ",
                " != ",
                " <= ",
                " >= ",
                " += ",
                " -= ",
                " *= ",
                " /= ",
                " %= ",
                " <<= ",
                " >>= ",
                " &= ",
                " |= ",
                " ^= ",
                " ++ ",
                " -- ",
                " //",
                " /*",
                "*/ ",
                " float",
                " half",
                " int",
                " uint",
                " short",
                " ushort",
                " bool",
                " void",
                " vec",
                " ivec",
                " bvec",
                " mat",
                " Attributes ",
                " Varyings ",
        });

        c %= std::size(kSkSLData);
        str->append(kSkSLData[c]);
        return true;
    };

    // Pick a vertex stride; intentionally allow some bad values through.
    vertexStride = extract<uint16_t>(data) % (SkMeshSpecification::kMaxStride + 2);

    while (!data.empty()) {
        uint8_t control = extract<uint8_t>(data) % 4;
        // A control code with no payload can be ignored.
        if (data.empty()) {
            break;
        }
        switch (control) {
            case 0: {
                // Add an attribute.
                Attribute& a = attributes.push_back();
                a.type = (Attribute::Type)(extract<uint8_t>(data) %
                                           ((int)Attribute::Type::kLast + 1));
                a.offset = extract<uint16_t>(data) % (SkMeshSpecification::kMaxStride + 2);
                while (uint8_t c = extract<char>(data)) {
                    if (!fuzzByteToASCII(c, &a.name)) {
                        break;
                    }
                }
                break;
            }
            case 1: {
                // Add a varying.
                Varying& v = varyings.push_back();
                v.type = (Varying::Type)(extract<uint8_t>(data) % ((int)Varying::Type::kLast + 1));
                while (uint8_t c = extract<char>(data)) {
                    if (!fuzzByteToASCII(c, &v.name)) {
                        break;
                    }
                }
                break;
            }
            case 2: {
                // Convert the following data into SkSL and add it into the vertex program.
                while (uint8_t c = extract<char>(data)) {
                    if (!fuzzByteToSkSL(c, &vs)) {
                        break;
                    }
                }
                break;
            }
            case 3: {
                // Convert the following data into SkSL and add it into the fragment program.
                while (uint8_t c = extract<char>(data)) {
                    if (!fuzzByteToSkSL(c, &fs)) {
                        break;
                    }
                }
                break;
            }
        }
    }

    auto result = SkMeshSpecification::Make(attributes, vertexStride, varyings, vs, fs);
    if (result.error.isEmpty()) {
        // TODO: synthesize a mesh with this specification and paint it.
        printf("----\n%s\n----\n\n----\n%s\n----\n\n\n", vs.c_str(), fs.c_str());
    }
}

#if defined(SK_BUILD_FOR_LIBFUZZER)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    if (size > 8000) {
        return 0;
    }
    FuzzSkMeshSpecification(data, size);
    return 0;
}
#endif
