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

#include "src/pdf/SkPDFTypes.h"

#include "include/core/SkData.h"
#include "include/core/SkExecutor.h"
#include "include/core/SkStream.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkStreamPriv.h"
#include "src/pdf/SkDeflate.h"
#include "src/pdf/SkPDFDocumentPriv.h"
#include "src/pdf/SkPDFUnion.h"
#include "src/pdf/SkPDFUtils.h"

#include <new>

////////////////////////////////////////////////////////////////////////////////

SkPDFUnion::SkPDFUnion(Type t, int32_t     v) : fIntValue          (v) , fType(t) {}
SkPDFUnion::SkPDFUnion(Type t, bool        v) : fBoolValue         (v) , fType(t) {}
SkPDFUnion::SkPDFUnion(Type t, SkScalar    v) : fScalarValue       (v) , fType(t) {}
SkPDFUnion::SkPDFUnion(Type t, const char* v) : fStaticString      (v) , fType(t) {}
SkPDFUnion::SkPDFUnion(Type t, SkString    v) : fSkString(std::move(v)), fType(t) {}
SkPDFUnion::SkPDFUnion(Type t, PDFObject   v) : fObject  (std::move(v)), fType(t) {}

SkPDFUnion::~SkPDFUnion() {
    switch (fType) {
        case Type::kNameSkS:
        case Type::kByteStringSkS:
        case Type::kTextStringSkS:
            fSkString.~SkString();
            return;
        case Type::kObject:
            fObject.~PDFObject();
            return;
        default:
            return;
    }
}

SkPDFUnion::SkPDFUnion(SkPDFUnion&& that) : fType(that.fType) {
    SkASSERT(this != &that);

    switch (fType) {
        case Type::kDestroyed:
            break;
        case Type::kInt:
        case Type::kColorComponent:
        case Type::kRef:
            fIntValue = that.fIntValue;
            break;
        case Type::kBool:
            fBoolValue = that.fBoolValue;
            break;
        case Type::kColorComponentF:
        case Type::kScalar:
            fScalarValue = that.fScalarValue;
            break;
        case Type::kName:
        case Type::kByteString:
        case Type::kTextString:
            fStaticString = that.fStaticString;
            break;
        case Type::kNameSkS:
        case Type::kByteStringSkS:
        case Type::kTextStringSkS:
            new (&fSkString) SkString(std::move(that.fSkString));
            break;
        case Type::kObject:
            new (&fObject) PDFObject(std::move(that.fObject));
            break;
        default:
            SkDEBUGFAIL("SkPDFUnion::SkPDFUnion with bad type");
    }
    that.fType = Type::kDestroyed;
}

SkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& that) {
    if (this != &that) {
        this->~SkPDFUnion();
        new (this) SkPDFUnion(std::move(that));
    }
    return *this;
}

bool SkPDFUnion::isName() const {
    return Type::kName == fType || Type::kNameSkS == fType;
}

#ifdef SK_DEBUG
// Most names need no escaping.  Such names are handled as static const strings.
bool is_valid_name(const char* n) {
    static const char kControlChars[] = "/%()<>[]{}";
    while (*n) {
        if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) {
            return false;
        }
        ++n;
    }
    return true;
}
#endif  // SK_DEBUG

// Given an arbitrary string, write it as a valid name (not including leading slash).
static void write_name_escaped(SkWStream* o, const char* name) {
    static const char kToEscape[] = "#/%()<>[]{}";
    for (const uint8_t* n = reinterpret_cast<const uint8_t*>(name); *n; ++n) {
        uint8_t v = *n;
        if (v < '!' || v > '~' || strchr(kToEscape, v)) {
            char buffer[3] = {'#',
                              SkHexadecimalDigits::gUpper[v >> 4],
                              SkHexadecimalDigits::gUpper[v & 0xF]};
            o->write(buffer, sizeof(buffer));
        } else {
            o->write(n, 1);
        }
    }
}

static void write_literal_byte_string(SkWStream* wStream, const char* cin, size_t len) {
    wStream->writeText("(");
    for (size_t i = 0; i < len; i++) {
        uint8_t c = static_cast<uint8_t>(cin[i]);
        if (c < ' ' || '~' < c) {
            uint8_t octal[4] = { '\\',
                                 (uint8_t)('0' | ( c >> 6        )),
                                 (uint8_t)('0' | ((c >> 3) & 0x07)),
                                 (uint8_t)('0' | ( c       & 0x07)) };
            wStream->write(octal, 4);
        } else {
            if (c == '\\' || c == '(' || c == ')') {
                wStream->writeText("\\");
            }
            wStream->write(&c, 1);
        }
    }
    wStream->writeText(")");
}

static void write_hex_byte_string(SkWStream* wStream, const char* cin, size_t len) {
    SkDEBUGCODE(static const size_t kMaxLen = 65535;)
    SkASSERT(len <= kMaxLen);

    wStream->writeText("<");
    for (size_t i = 0; i < len; i++) {
        uint8_t c = static_cast<uint8_t>(cin[i]);
        char hexValue[2] = { SkHexadecimalDigits::gUpper[c >> 4],
                             SkHexadecimalDigits::gUpper[c & 0xF] };
        wStream->write(hexValue, 2);
    }
    wStream->writeText(">");
}

static void write_optimized_byte_string(SkWStream* wStream, const char* cin, size_t len,
                                        size_t literalExtras) {
    const size_t hexLength     = 2 + 2*len;
    const size_t literalLength = 2 +   len + literalExtras;
    if (literalLength <= hexLength) {
        write_literal_byte_string(wStream, cin, len);
    } else {
        write_hex_byte_string(wStream, cin, len);
    }
}

static void write_byte_string(SkWStream* wStream, const char* cin, size_t len) {
    SkDEBUGCODE(static const size_t kMaxLen = 65535;)
    SkASSERT(len <= kMaxLen);

    size_t literalExtras = 0;
    {
        for (size_t i = 0; i < len; i++) {
            uint8_t c = static_cast<uint8_t>(cin[i]);
            if (c < ' ' || '~' < c) {
                literalExtras += 3;
            } else if (c == '\\' || c == '(' || c == ')') {
                ++literalExtras;
            }
        }
    }
    write_optimized_byte_string(wStream, cin, len, literalExtras);
}

static void write_text_string(SkWStream* wStream, const char* cin, size_t len) {
    SkDEBUGCODE(static const size_t kMaxLen = 65535;)
    SkASSERT(len <= kMaxLen);

    bool inputIsValidUTF8 = true;
    bool inputIsPDFDocEncoding = true;
    size_t literalExtras = 0;
    {
        const char* textPtr = cin;
        const char* textEnd = cin + len;
        while (textPtr < textEnd) {
            SkUnichar unichar = SkUTF::NextUTF8(&textPtr, textEnd);
            if (unichar < 0) {
                inputIsValidUTF8 = false;
                break;
            }
            // See Table D.2 (PDFDocEncoding Character Set) in the PDF3200_2008 spec.
            // Could convert from UTF-8 to PDFDocEncoding and, if successful, use that.
            if ((0x15 < unichar && unichar < 0x20) || 0x7E < unichar) {
                inputIsPDFDocEncoding = false;
                break;
            }
            if (unichar < ' ' || '~' < unichar) {
                literalExtras += 3;
            } else if (unichar == '\\' || unichar == '(' || unichar == ')') {
                ++literalExtras;
            }
        }
    }

    if (!inputIsValidUTF8) {
        SkDebugf("Invalid UTF8: %.*s\n", (int)len, cin);
        wStream->writeText("<>");
        return;
    }

    if (inputIsPDFDocEncoding) {
        write_optimized_byte_string(wStream, cin, len, literalExtras);
        return;
    }

    wStream->writeText("<FEFF");
    const char* textPtr = cin;
    const char* textEnd = cin + len;
    while (textPtr < textEnd) {
        SkUnichar unichar = SkUTF::NextUTF8(&textPtr, textEnd);
        SkPDFUtils::WriteUTF16beHex(wStream, unichar);
    }
    wStream->writeText(">");
}

void SkPDFWriteTextString(SkWStream* wStream, const char* cin, size_t len) {
    write_text_string(wStream, cin, len);
}
void SkPDFWriteByteString(SkWStream* wStream, const char* cin, size_t len) {
    write_byte_string(wStream, cin, len);
}

void SkPDFUnion::emitObject(SkWStream* stream) const {
    switch (fType) {
        case Type::kInt:
            stream->writeDecAsText(fIntValue);
            return;
        case Type::kColorComponent:
            SkPDFUtils::AppendColorComponent(SkToU8(fIntValue), stream);
            return;
        case Type::kColorComponentF:
            SkPDFUtils::AppendColorComponentF(fScalarValue, stream);
            return;
        case Type::kBool:
            stream->writeText(fBoolValue ? "true" : "false");
            return;
        case Type::kScalar:
            SkPDFUtils::AppendScalar(fScalarValue, stream);
            return;
        case Type::kName:
            stream->writeText("/");
            SkASSERT(is_valid_name(fStaticString));
            stream->writeText(fStaticString);
            return;
        case Type::kByteString:
            SkASSERT(fStaticString);
            write_byte_string(stream, fStaticString, strlen(fStaticString));
            return;
        case Type::kTextString:
            SkASSERT(fStaticString);
            write_text_string(stream, fStaticString, strlen(fStaticString));
            return;
        case Type::kNameSkS:
            stream->writeText("/");
            write_name_escaped(stream, fSkString.c_str());
            return;
        case Type::kByteStringSkS:
            write_byte_string(stream, fSkString.c_str(), fSkString.size());
            return;
        case Type::kTextStringSkS:
            write_text_string(stream, fSkString.c_str(), fSkString.size());
            return;
        case Type::kObject:
            fObject->emitObject(stream);
            return;
        case Type::kRef:
            SkASSERT(fIntValue >= 0);
            stream->writeDecAsText(fIntValue);
            stream->writeText(" 0 R");  // Generation number is always 0.
            return;
        default:
            SkDEBUGFAIL("SkPDFUnion::emitObject with bad type");
    }
}

SkPDFUnion SkPDFUnion::Int(int32_t value) {
    return SkPDFUnion(Type::kInt, value);
}

SkPDFUnion SkPDFUnion::ColorComponent(uint8_t value) {
    return SkPDFUnion(Type::kColorComponent,  SkTo<int32_t>(value));
}

SkPDFUnion SkPDFUnion::ColorComponentF(float value) {
    return SkPDFUnion(Type::kColorComponentF, SkFloatToScalar(value));
}

SkPDFUnion SkPDFUnion::Bool(bool value) {
    return SkPDFUnion(Type::kBool, value);
}

SkPDFUnion SkPDFUnion::Scalar(SkScalar value) {
    return SkPDFUnion(Type::kScalar, value);
}

SkPDFUnion SkPDFUnion::Name(const char* value) {
    SkASSERT(value);
    SkASSERT(is_valid_name(value));
    return SkPDFUnion(Type::kName, value);
}

SkPDFUnion SkPDFUnion::ByteString(const char* value) {
    SkASSERT(value);
    return SkPDFUnion(Type::kByteString, value);
}

SkPDFUnion SkPDFUnion::TextString(const char* value) {
    SkASSERT(value);
    return SkPDFUnion(Type::kTextString, value);
}

SkPDFUnion SkPDFUnion::Name(SkString s) {
    return SkPDFUnion(Type::kNameSkS, std::move(s));
}

SkPDFUnion SkPDFUnion::ByteString(SkString s) {
    return SkPDFUnion(Type::kByteStringSkS, std::move(s));
}

SkPDFUnion SkPDFUnion::TextString(SkString s) {
    return SkPDFUnion(Type::kTextStringSkS, std::move(s));
}

SkPDFUnion SkPDFUnion::Object(std::unique_ptr<SkPDFObject> objSp) {
    SkASSERT(objSp.get());
    return SkPDFUnion(Type::kObject, std::move(objSp));
}

SkPDFUnion SkPDFUnion::Ref(SkPDFIndirectReference ref) {
    SkASSERT(ref.fValue > 0);
    return SkPDFUnion(Type::kRef, SkTo<int32_t>(ref.fValue));
}

////////////////////////////////////////////////////////////////////////////////

#if 0  // Enable if needed.
void SkPDFAtom::emitObject(SkWStream* stream) const {
    fValue.emitObject(stream);
}
#endif  // 0

////////////////////////////////////////////////////////////////////////////////

SkPDFArray::SkPDFArray() {}

SkPDFArray::~SkPDFArray() {}

size_t SkPDFArray::size() const { return fValues.size(); }

void SkPDFArray::reserve(int length) {
    fValues.reserve(length);
}

void SkPDFArray::emitObject(SkWStream* stream) const {
    stream->writeText("[");
    for (size_t i = 0; i < fValues.size(); i++) {
        fValues[i].emitObject(stream);
        if (i + 1 < fValues.size()) {
            stream->writeText(" ");
        }
    }
    stream->writeText("]");
}

void SkPDFArray::append(SkPDFUnion&& value) {
    fValues.emplace_back(std::move(value));
}

void SkPDFArray::appendInt(int32_t value) {
    this->append(SkPDFUnion::Int(value));
}

void SkPDFArray::appendColorComponent(uint8_t value) {
    this->append(SkPDFUnion::ColorComponent(value));
}

void SkPDFArray::appendBool(bool value) {
    this->append(SkPDFUnion::Bool(value));
}

void SkPDFArray::appendScalar(SkScalar value) {
    this->append(SkPDFUnion::Scalar(value));
}

void SkPDFArray::appendName(const char name[]) {
    this->append(SkPDFUnion::Name(SkString(name)));
}

void SkPDFArray::appendName(SkString name) {
    this->append(SkPDFUnion::Name(std::move(name)));
}

void SkPDFArray::appendByteString(SkString value) {
    this->append(SkPDFUnion::ByteString(std::move(value)));
}

void SkPDFArray::appendTextString(SkString value) {
    this->append(SkPDFUnion::TextString(std::move(value)));
}

void SkPDFArray::appendByteString(const char value[]) {
    this->append(SkPDFUnion::ByteString(value));
}

void SkPDFArray::appendTextString(const char value[]) {
    this->append(SkPDFUnion::TextString(value));
}

void SkPDFArray::appendObject(std::unique_ptr<SkPDFObject>&& objSp) {
    this->append(SkPDFUnion::Object(std::move(objSp)));
}

void SkPDFArray::appendRef(SkPDFIndirectReference ref) {
    this->append(SkPDFUnion::Ref(ref));
}

///////////////////////////////////////////////////////////////////////////////

SkPDFDict::~SkPDFDict() {}

SkPDFDict::SkPDFDict(const char type[]) {
    if (type) {
        this->insertName("Type", type);
    }
}

void SkPDFDict::emitObject(SkWStream* stream) const {
    stream->writeText("<<");
    for (size_t i = 0; i < fRecords.size(); ++i) {
        const std::pair<SkPDFUnion, SkPDFUnion>& record = fRecords[i];
        record.first.emitObject(stream);
        stream->writeText(" ");
        record.second.emitObject(stream);
        if (i + 1 < fRecords.size()) {
            stream->writeText("\n");
        }
    }
    stream->writeText(">>");
}

size_t SkPDFDict::size() const { return fRecords.size(); }

void SkPDFDict::reserve(int n) {
    fRecords.reserve(n);
}

void SkPDFDict::insertRef(const char key[], SkPDFIndirectReference ref) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Ref(ref));
}

void SkPDFDict::insertRef(SkString key, SkPDFIndirectReference ref) {
    fRecords.emplace_back(SkPDFUnion::Name(std::move(key)), SkPDFUnion::Ref(ref));
}

void SkPDFDict::insertObject(const char key[], std::unique_ptr<SkPDFObject>&& objSp) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Object(std::move(objSp)));
}
void SkPDFDict::insertObject(SkString key, std::unique_ptr<SkPDFObject>&& objSp) {
    fRecords.emplace_back(SkPDFUnion::Name(std::move(key)),
                          SkPDFUnion::Object(std::move(objSp)));
}

void SkPDFDict::insertBool(const char key[], bool value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Bool(value));
}

void SkPDFDict::insertInt(const char key[], int32_t value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Int(value));
}

void SkPDFDict::insertInt(const char key[], size_t value) {
    this->insertInt(key, SkToS32(value));
}

void SkPDFDict::insertColorComponentF(const char key[], SkScalar value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ColorComponentF(value));
}

void SkPDFDict::insertScalar(const char key[], SkScalar value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value));
}

void SkPDFDict::insertName(const char key[], const char name[]) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
}

void SkPDFDict::insertName(const char key[], SkString name) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::Name(std::move(name)));
}

void SkPDFDict::insertByteString(const char key[], const char value[]) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ByteString(value));
}

void SkPDFDict::insertTextString(const char key[], const char value[]) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::TextString(value));
}

void SkPDFDict::insertByteString(const char key[], SkString value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::ByteString(std::move(value)));
}

void SkPDFDict::insertTextString(const char key[], SkString value) {
    fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::TextString(std::move(value)));
}

////////////////////////////////////////////////////////////////////////////////



static void serialize_stream(SkPDFDict* origDict,
                             SkStreamAsset* stream,
                             SkPDFSteamCompressionEnabled compress,
                             SkPDFDocument* doc,
                             SkPDFIndirectReference ref) {
    // Code assumes that the stream starts at the beginning.
    SkASSERT(stream && stream->hasLength());

    std::unique_ptr<SkStreamAsset> tmp;
    SkPDFDict tmpDict;
    SkPDFDict& dict = origDict ? *origDict : tmpDict;
    static const size_t kMinimumSavings = strlen("/Filter_/FlateDecode_");
    if (doc->metadata().fCompressionLevel != SkPDF::Metadata::CompressionLevel::None &&
        compress == SkPDFSteamCompressionEnabled::Yes &&
        stream->getLength() > kMinimumSavings)
    {
        SkDynamicMemoryWStream compressedData;
        SkDeflateWStream deflateWStream(&compressedData,SkToInt(doc->metadata().fCompressionLevel));
        SkStreamCopy(&deflateWStream, stream);
        deflateWStream.finalize();
        #ifdef SK_PDF_BASE85_BINARY
        {
            SkPDFUtils::Base85Encode(compressedData.detachAsStream(), &compressedData);
            tmp = compressedData.detachAsStream();
            stream = tmp.get();
            auto filters = SkPDFMakeArray();
            filters->appendName("ASCII85Decode");
            filters->appendName("FlateDecode");
            dict.insertObject("Filter", std::move(filters));
        }
        #else
        if (stream->getLength() > compressedData.bytesWritten() + kMinimumSavings) {
            tmp = compressedData.detachAsStream();
            stream = tmp.get();
            dict.insertName("Filter", "FlateDecode");
        } else {
            SkAssertResult(stream->rewind());
        }
        #endif

    }
    dict.insertInt("Length", stream->getLength());
    doc->emitStream(dict,
                    [stream](SkWStream* dst) { dst->writeStream(stream, stream->getLength()); },
                    ref);
}

SkPDFIndirectReference SkPDFStreamOut(std::unique_ptr<SkPDFDict> dict,
                                      std::unique_ptr<SkStreamAsset> content,
                                      SkPDFDocument* doc,
                                      SkPDFSteamCompressionEnabled compress) {
    SkPDFIndirectReference ref = doc->reserveRef();
    if (SkExecutor* executor = doc->executor()) {
        SkPDFDict* dictPtr = dict.release();
        SkStreamAsset* contentPtr = content.release();
        // Pass ownership of both pointers into a std::function, which should
        // only be executed once.
        doc->incrementJobCount();
        executor->add([dictPtr, contentPtr, compress, doc, ref]() {
            serialize_stream(dictPtr, contentPtr, compress, doc, ref);
            delete dictPtr;
            delete contentPtr;
            doc->signalJobComplete();
        });
        return ref;
    }
    serialize_stream(dict.get(), content.get(), compress, doc, ref);
    return ref;
}
