/*
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"

#if HAVE(PDFKIT)

#import "PlatformUtilities.h"
#import "Test.h"
#import "TestPDFDocument.h"
#import "TestWKWebView.h"
#import <WebCore/Color.h>
#import <WebKit/WKWebViewPrivate.h>

using WebCore::Color;

namespace TestWebKitAPI {

TEST(PDFSnapshot, FullContent)
{
    static bool didTakeSnapshot;

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><body bgcolor=#00ff00>Hello</body>"];

    [webView _takePDFSnapshotWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 1u);
        auto page = document->page(0);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 800, 600)));

        EXPECT_EQ(page->characterCount(), 5u);
        EXPECT_EQ(page->text()[0], 'H');
        EXPECT_EQ(page->text()[4], 'o');

        // The entire page should be green. Pick a point in the middle to check.
        EXPECT_TRUE(page->colorAtPoint(400, 300) == Color::createUnchecked(0, 255, 0));

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
}

TEST(PDFSnapshot, Subregions)
{
    static bool didTakeSnapshot;

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><body bgcolor=#00ff00>Hello</body>"];

    // Snapshot a subregion contained entirely within the view
    auto snapshotConfiguration = adoptNS([[WKSnapshotConfiguration alloc] init]);
    [snapshotConfiguration setRect:NSMakeRect(200, 150, 400, 300)];
    [snapshotConfiguration setSnapshotWidth:@400];

    [webView _takePDFSnapshotWithConfiguration:snapshotConfiguration.get() completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 1u);
        auto page = document->page(0);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 400, 300)));

        EXPECT_EQ(page->characterCount(), 0u);

        // The entire page should be green. Pick a point in the middle to check.
        EXPECT_TRUE(page->colorAtPoint(200, 150) == Color::createUnchecked(0, 255, 0));

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
    didTakeSnapshot = false;

    // Snapshot a region larger than the view
    [snapshotConfiguration setRect:NSMakeRect(0, 0, 1200, 1200)];
    [snapshotConfiguration setSnapshotWidth:@1200];

    [webView _takePDFSnapshotWithConfiguration:snapshotConfiguration.get() completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 1u);
        auto page = document->page(0);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 1200, 1200)));

        // A pixel that was in the view should be green. Pick a point in the middle to check.
        EXPECT_TRUE(page->colorAtPoint(200, 150) == Color::createUnchecked(0, 255, 0));

        // A pixel that was outside the view should also be green (we extend background color out). Pick a point in the middle to check.
        EXPECT_TRUE(page->colorAtPoint(900, 700) == Color::createUnchecked(0, 255, 0));

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
    didTakeSnapshot = false;

}

TEST(PDFSnapshot, Over200Inches)
{
    static bool didTakeSnapshot;

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 29400)]);

    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><body bgcolor=#00ff00>Hello</body>"];

    [webView _takePDFSnapshotWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 3u);

        auto page = document->page(0);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 800, 14400)));
        EXPECT_TRUE(page->colorAtPoint(400, 300) == Color::createUnchecked(0, 255, 0));
        EXPECT_EQ(page->characterCount(), 5u);

        page = document->page(1);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 800, 14400)));
        EXPECT_TRUE(page->colorAtPoint(400, 300) == Color::createUnchecked(0, 255, 0));

        EXPECT_EQ(page->characterCount(), 0u);

        page = document->page(2);
        EXPECT_NE(page, nullptr);
        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 800, 600)));
        EXPECT_TRUE(page->colorAtPoint(400, 300) == Color::createUnchecked(0, 255, 0));
        EXPECT_EQ(page->characterCount(), 0u);

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
}

TEST(PDFSnapshot, Links)
{
    static bool didTakeSnapshot;

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 15000)]);
    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><div style=\"-webkit-line-box-contain: glyphs\"><a href=\"https://webkit.org/\">Click me</a></div>"];

    [webView _takePDFSnapshotWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 2u);

        auto page = document->page(0);
        EXPECT_NE(page, nullptr);

        EXPECT_TRUE(CGRectEqualToRect(page->bounds(), CGRectMake(0, 0, 800, 14400)));
        EXPECT_TRUE(page->colorAtPoint(400, 300) == Color::createUnchecked(255, 255, 255));

        EXPECT_EQ(page->characterCount(), 8u);
        EXPECT_EQ(page->text()[0], 'C');
        EXPECT_EQ(page->text()[7], 'e');

        auto annotations = page->annotations();
        EXPECT_EQ(annotations.size(), 1u);
        if (annotations.size()) {
            EXPECT_TRUE(annotations[0].isLink());
            EXPECT_TRUE([annotations[0].linkURL() isEqual:[NSURL URLWithString:@"https://webkit.org/"]]);

            auto cRect = page->rectForCharacterAtIndex(1);
            auto cMidpoint = CGPointMake(CGRectGetMidX(cRect), CGRectGetMidY(cRect));
            auto annotationBounds = annotations[0].bounds();

            EXPECT_TRUE(CGRectContainsPoint(annotationBounds, cMidpoint));
        }

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
}

TEST(PDFSnapshot, InlineLinks)
{
    static bool didTakeSnapshot;

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width'><a href=\"https://webkit.org/\">Click me</a>"];

    [webView _takePDFSnapshotWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) {
        EXPECT_NULL(error);
        auto document = TestPDFDocument::createFromData(pdfSnapshotData);
        EXPECT_EQ(document->pageCount(), 1u);

        auto page = document->page(0);
        EXPECT_NE(page, nullptr);

        // FIXME <rdar://problem/55086988>: There should be a link here, but due to the way we gather links for
        // annotation using the RenderInline tree it is missed.

//        auto annotations = page->annotations();
//        EXPECT_EQ(annotations.size(), 1u);
//        EXPECT_TRUE(annotations[0].isLink());
//        EXPECT_TRUE([annotations[0].linkURL() isEqual:[NSURL URLWithString:@"https://webkit.org/"]]);

        didTakeSnapshot = true;
    }];

    Util::run(&didTakeSnapshot);
}

}

#endif // HAVE(PDFKIT)
