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

#include "src/core/SkTextBlobTrace.h"

#include "include/core/SkTextBlob.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkPtrRecorder.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkTextBlobPriv.h"
#include "src/core/SkWriteBuffer.h"

std::vector<SkTextBlobTrace::Record> SkTextBlobTrace::CreateBlobTrace(SkStream* stream) {
    std::vector<SkTextBlobTrace::Record> trace;

    uint32_t typefaceCount;
    if (!stream->readU32(&typefaceCount)) {
        return trace;
    }

    std::vector<sk_sp<SkTypeface>> typefaceArray;
    for (uint32_t i = 0; i < typefaceCount; i++) {
        typefaceArray.push_back(SkTypeface::MakeDeserialize(stream));
    }

    uint32_t restOfFile;
    if (!stream->readU32(&restOfFile)) {
        return trace;
    }
    sk_sp<SkData> data = SkData::MakeFromStream(stream, restOfFile);
    SkReadBuffer readBuffer{data->data(), data->size()};
    readBuffer.setTypefaceArray(typefaceArray.data(), typefaceArray.size());

    while (!readBuffer.eof()) {
        SkTextBlobTrace::Record record;
        record.origUniqueID = readBuffer.readUInt();
        readBuffer.readPaint(&record.paint, nullptr);
        readBuffer.readPoint(&record.offset);
        record.blob = SkTextBlobPriv::MakeFromBuffer(readBuffer);
        trace.push_back(std::move(record));
    }
    return trace;
}

void SkTextBlobTrace::DumpTrace(const std::vector<SkTextBlobTrace::Record>& trace) {
    for (const SkTextBlobTrace::Record& record : trace) {
        const SkTextBlob* blob = record.blob.get();
        const SkPaint& p = record.paint;
        bool weirdPaint = p.getStyle() != SkPaint::kFill_Style
        || p.getMaskFilter() != nullptr
        || p.getPathEffect() != nullptr;

        SkDebugf("Blob %d ( %g %g ) %d\n  ",
                blob->uniqueID(), record.offset.x(), record.offset.y(), weirdPaint);
        SkTextBlobRunIterator iter(blob);
        int runNumber = 0;
        while (!iter.done()) {
            SkDebugf("Run %d\n    ", runNumber);
            SkFont font = iter.font();
            SkDebugf("Font %d %g %g %g %d %d %d\n    ",
                    font.getTypefaceOrDefault()->uniqueID(),
                    font.getSize(),
                    font.getScaleX(),
                    font.getSkewX(),
                    SkFontPriv::Flags(font),
                    font.getEdging(),
                    font.getHinting());
            uint32_t glyphCount = iter.glyphCount();
            const uint16_t* glyphs = iter.glyphs();
            for (uint32_t i = 0; i < glyphCount; i++) {
                SkDebugf("%02X ", glyphs[i]);
            }
            SkDebugf("\n");
            runNumber += 1;
            iter.next();
        }
    }
}

SkTextBlobTrace::Capture::Capture() : fTypefaceSet(new SkRefCntSet) {
    fWriteBuffer.setTypefaceRecorder(fTypefaceSet);
}

SkTextBlobTrace::Capture::~Capture() = default;

void SkTextBlobTrace::Capture::capture(const SkGlyphRunList& glyphRunList) {
    const SkTextBlob* blob = glyphRunList.blob();
    if (blob != nullptr) {
        fWriteBuffer.writeUInt(blob->uniqueID());
        fWriteBuffer.writePaint(glyphRunList.paint());
        fWriteBuffer.writePoint(glyphRunList.origin());
        SkTextBlobPriv::Flatten(*blob, fWriteBuffer);
        fBlobCount++;
    }
}

void SkTextBlobTrace::Capture::dump(SkWStream* dst) const {
    SkTLazy<SkFILEWStream> fileStream;
    if (!dst) {
        uint32_t id = SkChecksum::Mix(reinterpret_cast<uintptr_t>(this));
        SkString f = SkStringPrintf("diff-canvas-%08x-%04d.trace", id, fBlobCount);
        dst = fileStream.init(f.c_str());
        if (!fileStream->isValid()) {
            SkDebugf("Error opening '%s'.\n", f.c_str());
            return;
        }
        SkDebugf("Saving trace to '%s'.\n", f.c_str());
    }
    SkASSERT(dst);
    int count = fTypefaceSet->count();
    dst->write32(count);
    SkPtrSet::Iter iter(*fTypefaceSet);
    while (void* ptr = iter.next()) {
        ((const SkTypeface*)ptr)->serialize(dst, SkTypeface::SerializeBehavior::kDoIncludeData);
    }
    dst->write32(fWriteBuffer.bytesWritten());
    fWriteBuffer.writeToStream(dst);
}
