/*
 * 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 "fuzz/Fuzz.h"

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

static void FuzzSkMeshSpecification(SkSpan<const uint8_t> data) {
    using Attribute = SkMeshSpecification::Attribute;
    using Varying = SkMeshSpecification::Varying;

    SkSTArray<SkMeshSpecification::kMaxAttributes, Attribute> attributes;
    SkSTArray<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 std::string_view kSkSLData[] = {
                " 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;
        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());
    }
}

bool FuzzSkMeshSpecification(sk_sp<SkData> fuzz) {
    FuzzSkMeshSpecification(SkSpan(fuzz->bytes(), fuzz->size()));
    return true;
}

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