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

#include "SkCanvas.h"
#include "SkMutex.h"
#include "SkPDFDocument.h"
#include "SkPDFMetadata.h"
#include "SkPDFTag.h"
#include "SkStream.h"
#include "SkTHash.h"

#include <atomic>
#include <vector>
#include <memory>

class SkExecutor;
class SkPDFDevice;
class SkPDFFont;
struct SkAdvancedTypefaceMetrics;
struct SkBitmapKey;
struct SkPDFFillGraphicState;
struct SkPDFImageShaderKey;
struct SkPDFStrokeGraphicState;

namespace SkPDFGradientShader {
struct Key;
struct KeyHash;
}

const char* SkPDFGetNodeIdKey();

// Logically part of SkPDFDocument, but separate to keep similar functionality together.
class SkPDFOffsetMap {
public:
    void markStartOfDocument(const SkWStream*);
    void markStartOfObject(int referenceNumber, const SkWStream*);
    int objectCount() const;
    int emitCrossReferenceTable(SkWStream* s) const;
private:
    std::vector<int> fOffsets;
    size_t fBaseOffset = SIZE_MAX;
};


struct SkPDFNamedDestination {
    sk_sp<SkData> fName;
    SkPoint fPoint;
    SkPDFIndirectReference fPage;
};

/** Concrete implementation of SkDocument that creates PDF files. This
    class does not produced linearized or optimized PDFs; instead it
    it attempts to use a minimum amount of RAM. */
class SkPDFDocument : public SkDocument {
public:
    SkPDFDocument(SkWStream*, SkPDF::Metadata);
    ~SkPDFDocument() override;
    SkCanvas* onBeginPage(SkScalar, SkScalar) override;
    void onEndPage() override;
    void onClose(SkWStream*) override;
    void onAbort() override;

    /**
       Serialize the object, as well as any other objects it
       indirectly refers to.  If any any other objects have been added
       to the SkPDFObjNumMap without serializing them, they will be
       serialized as well.

       It might go without saying that objects should not be changed
       after calling serialize, since those changes will be too late.
     */
    SkPDFIndirectReference emit(const SkPDFObject&, SkPDFIndirectReference);
    SkPDFIndirectReference emit(const SkPDFObject& o) { return this->emit(o, this->reserveRef()); }

    template <typename T>
    void emitStream(const SkPDFDict& dict, T writeStream, SkPDFIndirectReference ref) {
        SkWStream* stream = this->beginObject(ref);
        dict.emitObject(stream);
        stream->writeText(" stream\n");
        writeStream(stream);
        stream->writeText("\nendstream");
        this->endObject();
    }

    const SkPDF::Metadata& metadata() const { return fMetadata; }

    SkPDFIndirectReference getPage(size_t pageIndex) const;
    SkPDFIndirectReference currentPage() const {
        return SkASSERT(!fPageRefs.empty()), fPageRefs.back();
    }
    // Returns -1 if no mark ID.
    int getMarkIdForNodeId(int nodeId);

    SkPDFIndirectReference reserveRef() { return SkPDFIndirectReference{fNextObjectNumber++}; }

    SkExecutor* executor() const { return fExecutor; }
    void incrementJobCount();
    void signalJobComplete();
    size_t currentPageIndex() { return fPages.size(); }
    size_t pageCount() { return fPageRefs.size(); }

    const SkMatrix& currentPageTransform() const;

    // Canonicalized objects
    SkTHashMap<SkPDFImageShaderKey, SkPDFIndirectReference> fImageShaderMap;
    SkTHashMap<SkPDFGradientShader::Key, SkPDFIndirectReference, SkPDFGradientShader::KeyHash>
        fGradientPatternMap;
    SkTHashMap<SkBitmapKey, SkPDFIndirectReference> fPDFBitmapMap;
    SkTHashMap<uint32_t, std::unique_ptr<SkAdvancedTypefaceMetrics>> fTypefaceMetrics;
    SkTHashMap<uint32_t, std::vector<SkString>> fType1GlyphNames;
    SkTHashMap<uint32_t, std::vector<SkUnichar>> fToUnicodeMap;
    SkTHashMap<uint32_t, SkPDFIndirectReference> fFontDescriptors;
    SkTHashMap<uint32_t, SkPDFIndirectReference> fType3FontDescriptors;
    SkTHashMap<uint64_t, SkPDFFont> fFontMap;
    SkTHashMap<SkPDFStrokeGraphicState, SkPDFIndirectReference> fStrokeGSMap;
    SkTHashMap<SkPDFFillGraphicState, SkPDFIndirectReference> fFillGSMap;
    SkPDFIndirectReference fInvertFunction;
    SkPDFIndirectReference fNoSmaskGraphicState;

    std::vector<std::pair<sk_sp<SkData>, SkRect>> fCurrentPageLinkToURLs;
    std::vector<std::pair<sk_sp<SkData>, SkRect>> fCurrentPageLinkToDestinations;
    std::vector<SkPDFNamedDestination> fNamedDestinations;

private:
    SkPDFOffsetMap fOffsetMap;
    SkCanvas fCanvas;
    std::vector<std::unique_ptr<SkPDFDict>> fPages;
    std::vector<SkPDFIndirectReference> fPageRefs;

    sk_sp<SkPDFDevice> fPageDevice;
    std::atomic<int> fNextObjectNumber = {1};
    std::atomic<int> fJobCount = {0};
    SkUUID fUUID;
    SkPDFIndirectReference fInfoDict;
    SkPDFIndirectReference fXMP;
    SkPDF::Metadata fMetadata;
    SkScalar fRasterScale = 1;
    SkScalar fInverseRasterScale = 1;
    SkExecutor* fExecutor = nullptr;

    // For tagged PDFs.
    SkPDFTagTree fTagTree;

    SkMutex fMutex;
    SkSemaphore fSemaphore;

    void waitForJobs();
    SkWStream* beginObject(SkPDFIndirectReference);
    void endObject();
};

#endif  // SkPDFDocumentPriv_DEFINED
