/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "Test.h"

#include "Resources.h"
#include "SkCanvas.h"
#include "SkExecutor.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
#include "SkPDFDocument.h"
#include "SkStream.h"

#include "sk_tool_utils.h"

static void test_empty(skiatest::Reporter* reporter) {
    SkDynamicMemoryWStream stream;

    auto doc = SkPDF::MakeDocument(&stream);

    doc->close();

    REPORTER_ASSERT(reporter, stream.bytesWritten() == 0);
}

static void test_abort(skiatest::Reporter* reporter) {
    SkDynamicMemoryWStream stream;
    auto doc = SkPDF::MakeDocument(&stream);

    SkCanvas* canvas = doc->beginPage(100, 100);
    canvas->drawColor(SK_ColorRED);
    doc->endPage();

    doc->abort();

    // Test that only the header is written, not the full document.
    REPORTER_ASSERT(reporter, stream.bytesWritten() < 256);
}

static void test_abortWithFile(skiatest::Reporter* reporter) {
    SkString tmpDir = skiatest::GetTmpDir();

    if (tmpDir.isEmpty()) {
        ERRORF(reporter, "missing tmpDir.");
        return;
    }

    SkString path = SkOSPath::Join(tmpDir.c_str(), "aborted.pdf");
    if (!SkFILEWStream(path.c_str()).isValid()) {
        ERRORF(reporter, "unable to write to: %s", path.c_str());
        return;
    }

    // Make sure doc's destructor is called to flush.
    {
        SkFILEWStream stream(path.c_str());
        auto doc = SkPDF::MakeDocument(&stream);

        SkCanvas* canvas = doc->beginPage(100, 100);
        canvas->drawColor(SK_ColorRED);
        doc->endPage();

        doc->abort();
    }

    FILE* file = fopen(path.c_str(), "r");
    // Test that only the header is written, not the full document.
    char buffer[256];
    REPORTER_ASSERT(reporter, fread(buffer, 1, sizeof(buffer), file) < sizeof(buffer));
    fclose(file);
}

static void test_file(skiatest::Reporter* reporter) {
    SkString tmpDir = skiatest::GetTmpDir();
    if (tmpDir.isEmpty()) {
        ERRORF(reporter, "missing tmpDir.");
        return;
    }

    SkString path = SkOSPath::Join(tmpDir.c_str(), "file.pdf");
    if (!SkFILEWStream(path.c_str()).isValid()) {
        ERRORF(reporter, "unable to write to: %s", path.c_str());
        return;
    }

    {
        SkFILEWStream stream(path.c_str());
        auto doc = SkPDF::MakeDocument(&stream);
        SkCanvas* canvas = doc->beginPage(100, 100);

        canvas->drawColor(SK_ColorRED);
        doc->endPage();
        doc->close();
    }

    FILE* file = fopen(path.c_str(), "r");
    REPORTER_ASSERT(reporter, file != nullptr);
    char header[100];
    REPORTER_ASSERT(reporter, fread(header, 4, 1, file) != 0);
    REPORTER_ASSERT(reporter, strncmp(header, "%PDF", 4) == 0);
    fclose(file);
}

static void test_close(skiatest::Reporter* reporter) {
    SkDynamicMemoryWStream stream;
    auto doc = SkPDF::MakeDocument(&stream);

    SkCanvas* canvas = doc->beginPage(100, 100);
    canvas->drawColor(SK_ColorRED);
    doc->endPage();

    doc->close();

    REPORTER_ASSERT(reporter, stream.bytesWritten() != 0);
}

DEF_TEST(SkPDF_document_tests, reporter) {
    REQUIRE_PDF_DOCUMENT(document_tests, reporter);
    test_empty(reporter);
    test_abort(reporter);
    test_abortWithFile(reporter);
    test_file(reporter);
    test_close(reporter);
}

DEF_TEST(SkPDF_document_skbug_4734, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_document_skbug_4734, r);
    SkDynamicMemoryWStream stream;
    auto doc = SkPDF::MakeDocument(&stream);
    SkCanvas* canvas = doc->beginPage(64, 64);
    canvas->scale(10000.0f, 10000.0f);
    canvas->translate(20.0f, 10.0f);
    canvas->rotate(30.0f);
    const char text[] = "HELLO";
    canvas->drawString(text, 0, 0, SkFont(), SkPaint());
}

static bool contains(const uint8_t* result, size_t size, const char expectation[]) {
    size_t len = strlen(expectation);
    size_t N = 1 + size - len;
    for (size_t i = 0; i < N; ++i) {
        if (0 == memcmp(result + i, expectation, len)) {
            return true;
        }
    }
    return false;
}

// verify that the PDFA flag does something.
DEF_TEST(SkPDF_pdfa_document, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_pdfa_document, r);

    SkPDF::Metadata pdfMetadata;
    pdfMetadata.fTitle = "test document";
    pdfMetadata.fCreation = {0, 1999, 12, 5, 31, 23, 59, 59};
    pdfMetadata.fPDFA = true;

    SkDynamicMemoryWStream buffer;
    auto doc = SkPDF::MakeDocument(&buffer, pdfMetadata);
    doc->beginPage(64, 64)->drawColor(SK_ColorRED);
    doc->close();
    sk_sp<SkData> data(buffer.detachAsData());

    static const char* expectations[] = {
        "sRGB IEC61966-2.1",
        "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">test document",
        "<xmp:CreateDate>1999-12-31T23:59:59+00:00</xmp:CreateDate>",
        "/Subtype /XML",
        "/CreationDate (D:19991231235959+00'00')>>",
    };
    for (const char* expectation : expectations) {
        if (!contains(data->bytes(), data->size(), expectation)) {
            ERRORF(r, "PDFA expectation missing: '%s'.", expectation);
        }
    }
    pdfMetadata.fProducer = "phoney library";
    pdfMetadata.fPDFA = true;
    doc = SkPDF::MakeDocument(&buffer, pdfMetadata);
    doc->beginPage(64, 64)->drawColor(SK_ColorRED);
    doc->close();
    data = buffer.detachAsData();

    static const char* moreExpectations[] = {
        "/Producer (phoney library)",
        "/ProductionLibrary (Skia/PDF m",
        "<!-- <skia:ProductionLibrary>Skia/PDF m",
        "<pdf:Producer>phoney library</pdf:Producer>",
    };
    for (const char* expectation : moreExpectations) {
        if (!contains(data->bytes(), data->size(), expectation)) {
            ERRORF(r, "PDFA expectation missing: '%s'.", expectation);
        }
    }
}


DEF_TEST(SkPDF_unicode_metadata, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_unicode_metadata, r);
    SkPDF::Metadata pdfMetadata;
    pdfMetadata.fTitle   = "𝓐𝓑𝓒𝓓𝓔 𝓕𝓖𝓗𝓘𝓙"; // Out of basic multilingual plane
    pdfMetadata.fAuthor  = "ABCDE FGHIJ"; // ASCII
    pdfMetadata.fSubject = "αβγδε ζηθικ"; // inside  basic multilingual plane
    pdfMetadata.fPDFA = true;
    SkDynamicMemoryWStream wStream;
    {
        auto doc = SkPDF::MakeDocument(&wStream, pdfMetadata);
        doc->beginPage(612, 792)->drawColor(SK_ColorCYAN);
    }
    sk_sp<SkData> data(wStream.detachAsData());
    static const char* expectations[] = {
        "<</Title <FEFFD835DCD0D835DCD1D835DCD2D835DCD3D835DCD40020"
            "D835DCD5D835DCD6D835DCD7D835DCD8D835DCD9>",
        "/Author (ABCDE FGHIJ)",
        "Subject <FEFF03B103B203B303B403B5002003B603B703B803B903BA>",
    };
    for (const char* expectation : expectations) {
        if (!contains(data->bytes(), data->size(), expectation)) {
            ERRORF(r, "PDF expectation missing: '%s'.", expectation);
        }
    }
}

// Make sure we excercise the multi-page functionality without problems.
// Add this to args.gn to output the PDF to a file:
//   extra_cflags = [ "-DSK_PDF_TEST_MULTIPAGE=\"/tmp/skpdf_test_multipage.pdf\"" ]
DEF_TEST(SkPDF_multiple_pages, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_multiple_pages, r);
    int n = 100;
#ifdef SK_PDF_TEST_MULTIPAGE
    SkFILEWStream wStream(SK_PDF_TEST_MULTIPAGE);
#else
    SkDynamicMemoryWStream wStream;
#endif
    auto doc = SkPDF::MakeDocument(&wStream);
    for (int i = 0; i < n; ++i) {
        doc->beginPage(612, 792)->drawColor(
                SkColorSetARGB(0xFF, 0x00, (uint8_t)(255.0f * i / (n - 1)), 0x00));
    }
}

// Test to make sure that jobs launched by PDF backend don't cause a segfault
// after calling abort().
DEF_TEST(SkPDF_abort_jobs, rep) {
    SkBitmap b;
    b.allocN32Pixels(612, 792);
    b.eraseColor(0x4F9643A0);
    SkPDF::Metadata metadata;
    std::unique_ptr<SkExecutor> executor = SkExecutor::MakeFIFOThreadPool();
    metadata.fExecutor = executor.get();
    SkNullWStream dst;
    auto doc = SkPDF::MakeDocument(&dst, metadata);
    doc->beginPage(612, 792)->drawBitmap(b, 0, 0);
    doc->abort();
}

