/*
 * 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/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,
                             bool deflate,
                             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 (deflate && stream->getLength() > kMinimumSavings) {
        SkDynamicMemoryWStream compressedData;
        SkDeflateWStream deflateWStream(&compressedData);
        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,
                                      bool deflate) {
    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, deflate, doc, ref]() {
            serialize_stream(dictPtr, contentPtr, deflate, doc, ref);
            delete dictPtr;
            delete contentPtr;
            doc->signalJobComplete();
        });
        return ref;
    }
    serialize_stream(dict.get(), content.get(), deflate, doc, ref);
    return ref;
}
