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

#include "experimental/skrive/src/reader/StreamReader.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"

#include <vector>

namespace skrive::internal {

namespace {

class BinaryReader final : public StreamReader {
public:
    explicit BinaryReader(std::unique_ptr<SkStreamAsset> stream)
        : fStream(std::move(stream)) {}

private:
    bool validateSize(size_t sz) const {
        const auto next_pos  = fStream->getPosition() + sz,
                   block_end = fBlockStack.empty() ? fStream->getLength()
                                                   : fBlockStack.back().block_end;
        return next_pos <= block_end;
    }

    uint16_t readId(const char label[]) override {
        return this->readUInt16(label);
    }

    bool readBool(const char[]) override {
        uint8_t v;

        return validateSize(sizeof(v)) && fStream->readU8(&v)
                ? v == 1
                : false;
    }

    float readFloat(const char[]) override {
        float v;

        return validateSize(sizeof(v)) && fStream->readScalar(&v)
                ? v
                : 0.0f;
    }

    uint8_t readUInt8(const char[]) override {
        uint8_t v;

        return validateSize(sizeof(v)) && fStream->readU8(&v)
                ? v
                : 0;
    }

    uint16_t readUInt16(const char[]) override {
        uint16_t v;

        return validateSize(sizeof(v)) && fStream->readU16(&v)
                ? v
                : 0;
    }

    uint32_t readUInt32(const char[]) override {
        uint32_t v;

        return validateSize(sizeof(v)) && fStream->readU32(&v)
                ? v
                : 0;
    }

    SkString readString(const char[]) override {
        uint32_t length;
        if (!validateSize(sizeof(length)) || !fStream->readU32(&length)) {
            return SkString();
        }

        SkString str(length);
        return validateSize(length) && fStream->read(str.writable_str(), length) == length
            ? str
            : SkString();
    }

    size_t readFloatArray(const char[], float dst[], size_t count) override {
        if (!validateSize(count * sizeof(float))) {
            return 0;
        }

        return fStream->read(dst, count * sizeof(float)) / sizeof(float);
    }

    uint8_t readLength8() override {
        return this->readUInt8(nullptr);
    }

    uint16_t readLength16() override {
        return this->readUInt16(nullptr);
    }

    // nops
    bool   openArray(const char[]) override { return true; }
    void  closeArray()             override {}
    bool  openObject(const char[]) override { return true; }
    void closeObject()             override {}

    BlockType openBlock() override {
        uint8_t  block_type;
        uint32_t block_size;

        if (this->validateSize(sizeof(block_type) + sizeof(block_size)) &&
            fStream->readU8 (&block_type) &&
            fStream->readU32(&block_size)) {
            const auto block_end = std::min(fStream->getPosition() + block_size,
                                            fStream->getLength());
            fBlockStack.push_back({block_end});
            return static_cast<BlockType>(block_type);
        }

        return BlockType::kEoB;
    }

    void closeBlock() override {
        SkASSERT(!fBlockStack.empty());
        SkASSERT(fStream->getPosition() <= fBlockStack.back().block_end);

        if (fStream->getPosition() < fBlockStack.back().block_end) {
            const auto skip = fBlockStack.back().block_end - fStream->getPosition();
            SkDebugf("!! skipping %zu bytes in block\n", skip);
            fStream->skip(skip);
        }

        fBlockStack.pop_back();
    }

    const std::unique_ptr<SkStreamAsset> fStream;

    struct BlockRec {
        size_t block_end;
    };

    std::vector<BlockRec> fBlockStack;
};

} // namespace

std::unique_ptr<StreamReader> MakeBinaryStreamReader(std::unique_ptr<SkStreamAsset> stream) {
    return std::make_unique<BinaryReader>(std::move(stream));
}

}
