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

#ifndef skgpu_KeyBuilder_DEFINED
#define skgpu_KeyBuilder_DEFINED

#include "include/core/SkString.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkTArray.h"

#include <cstdint>
#include <string_view>

namespace skgpu {

class KeyBuilder {
public:
    KeyBuilder(skia_private::TArray<uint32_t, true>* data) : fData(data) {}

    virtual ~KeyBuilder() {
        // Ensure that flush was called before we went out of scope
        SkASSERT(fBitsUsed == 0);
    }

    virtual void addBits(uint32_t numBits, uint32_t val, std::string_view label) {
        SkASSERT(numBits > 0 && numBits <= 32);
        SkASSERT(numBits == 32 || (val < (1u << numBits)));

        fCurValue |= (val << fBitsUsed);
        fBitsUsed += numBits;

        if (fBitsUsed >= 32) {
            // Overflow, start a new working value
            fData->push_back(fCurValue);
            uint32_t excess = fBitsUsed - 32;
            fCurValue = excess ? (val >> (numBits - excess)) : 0;
            fBitsUsed = excess;
        }

        SkASSERT(fCurValue < (1u << fBitsUsed));
    }

    void addBytes(uint32_t numBytes, const void* data, std::string_view label) {
        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
        for (; numBytes --> 0; bytes++) {
            this->addBits(8, *bytes, label);
        }
    }

    void addBool(bool b, std::string_view label) {
        this->addBits(1, b, label);
    }

    void add32(uint32_t v, std::string_view label = "unknown") {
        this->addBits(32, v, label);
    }

    virtual void appendComment(const char* comment) {}

    // Introduces a word-boundary in the key. Must be called before using the key with any cache,
    // but can also be called to create a break between generic data and backend-specific data.
    void flush() {
        if (fBitsUsed) {
            fData->push_back(fCurValue);
            fCurValue = 0;
            fBitsUsed = 0;
        }
    }

private:
    skia_private::TArray<uint32_t, true>* fData;
    uint32_t fCurValue = 0;
    uint32_t fBitsUsed = 0;  // ... in current value
};

class StringKeyBuilder : public KeyBuilder {
public:
    StringKeyBuilder(skia_private::TArray<uint32_t, true>* data) : KeyBuilder(data) {}

    void addBits(uint32_t numBits, uint32_t val, std::string_view label) override {
        KeyBuilder::addBits(numBits, val, label);
        fDescription.appendf("%.*s: %u\n", (int)label.size(), label.data(), val);
    }

    void appendComment(const char* comment) override {
        fDescription.appendf("%s\n", comment);
    }

    SkString description() const { return fDescription; }

private:
    SkString fDescription;
};

} // namespace skgpu

#endif // skgpu_KeyBuilder_DEFINED
