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

#ifdef SK_SUPPORT_PDF

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkDocument.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/docs/SkPDFDocument.h"
#include "include/docs/SkPDFJpegHelpers.h"
#include "src/pdf/SkPDFUtils.h"
#include "tools/fonts/FontToolUtils.h"

#include <memory>
#include <utility>
#include <vector>

using PDFTag = SkPDF::StructureElementNode;

// Test building a tagged PDF containing a table.
// Add this to args.gn to output the PDF to a file:
//   extra_cflags = [ "-DSK_PDF_TEST_TAGS_OUTPUT_PATH=\"/tmp/table.pdf\"" ]
DEF_TEST(SkPDF_tagged_table, r) {
    REQUIRE_PDF_DOCUMENT(SkPDF_tagged, r);
#ifdef SK_PDF_TEST_TAGS_OUTPUT_PATH
    SkFILEWStream outputStream(SK_PDF_TEST_TAGS_OUTPUT_PATH);
#else
    SkDynamicMemoryWStream outputStream;
#endif

    SkSize pageSize = SkSize::Make(612, 792);  // U.S. Letter

    SkPDF::Metadata metadata;
    metadata.fTitle = "Example Tagged Table PDF";
    metadata.fCreator = "Skia";
    SkPDF::DateTime now;
    SkPDFUtils::GetDateTime(&now);
    metadata.fCreation = now;
    metadata.fModified = now;
    metadata.jpegDecoder = SkPDF::JPEG::Decode;
    metadata.jpegEncoder = SkPDF::JPEG::Encode;

    constexpr int kRowCount = 5;
    constexpr int kColCount = 4;
    const char* cellData[kRowCount * kColCount] = {
        "Car Make and Model",   "Engine",   "City MPG", "Highway MPG",
        "Mitsubishi Mirage ES", "Gas",      "28",       "47",
        "Toyota Prius Three",   "Hybrid",   "43",       "59",
        "Nissan Leaf SL",       "Electric", "N/A",      nullptr,
        "Tesla Model 3",        nullptr,    "N/A",      nullptr
    };

    // The document tag.
    auto root = std::make_unique<PDFTag>();
    root->fNodeId = 1;
    root->fTypeString = "Document";
    root->fLang = "en-US";

    // Heading.
    auto h1 = std::make_unique<PDFTag>();
    h1->fNodeId = 2;
    h1->fTypeString = "H1";
    h1->fAlt = "Tagged PDF Table Alt Text";
    root->fChildVector.push_back(std::move(h1));

    // Table.
    auto table = std::make_unique<PDFTag>();
    table->fNodeId = 3;
    table->fTypeString = "Table";
    auto& rows = table->fChildVector;
    table->fAttributes.appendFloatArray("Layout", "BBox", {72, 72, 360, 360});
    table->fAttributes.appendTextString("Table", "Summary", "Fuel efficiency");

    for (int rowIndex = 0; rowIndex < kRowCount; rowIndex++) {
        auto row = std::make_unique<PDFTag>();
        row->fNodeId = 4 + rowIndex;
        row->fTypeString = "TR";
        auto& cells = row->fChildVector;
        for (int colIndex = 0; colIndex < kColCount; colIndex++) {
            auto cell = std::make_unique<PDFTag>();
            int cellIndex = rowIndex * kColCount + colIndex;
            cell->fNodeId = 10 + cellIndex;
            if (!cellData[cellIndex]) {
                cell->fTypeString = "NonStruct";
            } else if (rowIndex == 0 || colIndex == 0) {
                cell->fTypeString = "TH";
                cell->fAttributes.appendTextString("Table", "Short", SkString("Car"));
            } else {
                cell->fTypeString = "TD";
                std::vector<int> headerIds;
                headerIds.push_back(10 + rowIndex * kColCount);  // Row header
                headerIds.push_back(10 + colIndex);  // Col header.
                cell->fAttributes.appendNodeIdArray(
                    "Table", "Headers", headerIds);
            }

            if (cellIndex == 13) {
                cell->fAttributes.appendInt("Table", "RowSpan", 2);
            } else if (cellIndex == 14 || cellIndex == 18) {
                cell->fAttributes.appendInt("Table", "ColSpan", 2);
            } else if (rowIndex == 0 || colIndex == 0) {
                cell->fAttributes.appendName(
                    "Table", "Scope", rowIndex == 0 ? "Column" : "Row");
            }
            cells.push_back(std::move(cell));
        }
        rows.push_back(std::move(row));
    }
    root->fChildVector.push_back(std::move(table));

    metadata.fStructureElementTreeRoot = root.get();
    sk_sp<SkDocument> document = SkPDF::MakeDocument(
        &outputStream, metadata);

    SkPaint paint;
    paint.setColor(SK_ColorBLACK);

    SkCanvas* canvas =
            document->beginPage(pageSize.width(),
                                pageSize.height());
    SkPDF::SetNodeId(canvas, 2);
    SkFont font(ToolUtils::DefaultTypeface(), 36);
    canvas->drawString("Tagged PDF Table", 72, 72, font, paint);

    font.setSize(14);
    for (int rowIndex = 0; rowIndex < kRowCount; rowIndex++) {
        for (int colIndex = 0; colIndex < kColCount; colIndex++) {
            int cellIndex = rowIndex * kColCount + colIndex;
            const char* str = cellData[cellIndex];
            if (!str)
                continue;

            int x = 72 + colIndex * 108 + (colIndex > 0 ? 72 : 0);
            int y = 144 + rowIndex * 48;

            SkPDF::SetNodeId(canvas, 10 + cellIndex);
            canvas->drawString(str, x, y, font, paint);
        }
    }

    document->endPage();
    document->close();
    outputStream.flush();
}

#endif
