// Copyright (C) 2025 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.

#if HAVE_PDFKIT

import Foundation
import WebKit
import PDFKit
import CoreGraphics
private import pal.spi.cg.CoreGraphicsSPI

#if canImport(UIKit)
import UIKit
typealias CocoaColor = UIColor
#else
import AppKit
typealias CocoaColor = NSColor
#endif

@objc
@implementation
extension TestPDFAnnotation {
    @nonobjc
    private var annotation: PDFAnnotation

    var isLink: Bool {
        let link = annotation.type == "Link"
        assert(!link || annotation.action is PDFActionURL)
        return link
    }

    var bounds: CGRect {
        annotation.bounds
    }

    var linkURL: URL? {
        guard isLink else {
            return nil
        }

        return (annotation.action as? PDFActionURL)?.url
    }

    @objc(initWithPDFAnnotation:)
    init(pdfAnnotation: PDFAnnotation) {
        self.annotation = pdfAnnotation
    }
}

@objc
@implementation
extension TestPDFPage {
    @nonobjc
    private var page: PDFPage

    lazy var text: String = {
        page.string?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
    }()

    var bounds: CGRect {
        page.bounds(for: .mediaBox)
    }

    var characterCount: Int {
        text.count
    }

    lazy var annotations: [TestPDFAnnotation] = { @MainActor in
        page.annotations.map(TestPDFAnnotation.init(pdfAnnotation:))
    }()

    @objc(characterIndexAtPoint:)
    func characterIndex(at point: CGPoint) -> Int {
        page.characterIndex(at: point)
    }

    @objc(colorAtPoint:)
    func color(at point: CGPoint) -> CocoaColor {
        let boundsRect = bounds
        let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)

        #if swift(>=6.2)
        // FIXME: document safety invariants here.
        #if HAVE_CGCONTEXT_INIT_WITH_BITMAP_INFO_AND_NULLABLE_COLORSPACE
        let context = unsafe CGContext(
            data: nil,
            width: Int(boundsRect.size.width),
            height: Int(boundsRect.size.height),
            bitsPerComponent: 8,
            bytesPerRow: 0,
            space: colorSpace,
            bitmapInfo: CGBitmapInfo(alpha: .premultipliedLast, byteOrder: .order32Big)
        )
        #else
        let context = unsafe CGContext(
            data: nil,
            width: Int(boundsRect.size.width),
            height: Int(boundsRect.size.height),
            bitsPerComponent: 8,
            bytesPerRow: 0,
            space: colorSpace!,
            bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big).rawValue
        )
        #endif
        #else
        #if HAVE_CGCONTEXT_INIT_WITH_BITMAP_INFO_AND_NULLABLE_COLORSPACE
        let context = CGContext(
            data: nil,
            width: Int(boundsRect.size.width),
            height: Int(boundsRect.size.height),
            bitsPerComponent: 8,
            bytesPerRow: 0,
            space: colorSpace,
            bitmapInfo: CGBitmapInfo(alpha: .premultipliedLast, byteOrder: .order32Big)
        )
        #else
        let context = CGContext(
            data: nil,
            width: Int(boundsRect.size.width),
            height: Int(boundsRect.size.height),
            bitsPerComponent: 8,
            bytesPerRow: 0,
            space: colorSpace!,
            bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big).rawValue
        )
        #endif
        #endif

        guard let context, let cgPage = page.pageRef else {
            fatalError()
        }

        CGContextDrawPDFPageWithAnnotations(context, cgPage, nil)

        let x = Int(point.x)
        let y = Int(point.y)
        let index = (y * x * 4) + (x * 4)

        #if swift(>=6.2)
        // FIXME: document safety invariants here. Is CGContext always guaranteed to
        // contain a context.data of the right size at this point?
        let pixels = unsafe UnsafeMutableRawBufferPointer(start: context.data, count: context.width * context.height * 4)
        let r = unsafe pixels[index]
        let g = unsafe pixels[index + 1]
        let b = unsafe pixels[index + 2]
        let a = unsafe pixels[index + 3]
        #else
        let pixels = UnsafeMutableRawBufferPointer(start: context.data, count: context.width * context.height * 4)
        let r = pixels[index]
        let g = pixels[index + 1]
        let b = pixels[index + 2]
        let a = pixels[index + 3]
        #endif

        if a == 0 {
            return .clear
        }

        let red = CGFloat(r) * 255 / CGFloat(a) / 255.0
        let green = CGFloat(g) * 255 / CGFloat(a) / 255.0
        let blue = CGFloat(b) * 255 / CGFloat(a) / 255.0
        let alpha = CGFloat(a) / 255.0

        return CocoaColor(red: red, green: green, blue: blue, alpha: alpha)
    }

    @objc(rectForCharacterAtIndex:)
    func rectForCharacter(at index: Int) -> CGRect {
        page.characterBounds(at: index)
    }

    @objc(initWithPDFPage:)
    init(pdfPage: PDFPage) {
        self.page = pdfPage
    }
}

@objc
@implementation
extension TestPDFDocument {
    @nonobjc
    private let document: PDFDocument
    @nonobjc
    private var pages: [TestPDFPage?]

    var pageCount: Int {
        document.pageCount
    }

    @objc(initFromData:)
    init(from data: Data) {
        let document = PDFDocument(data: data)!
        self.document = document
        self.pages = .init(repeating: nil, count: document.pageCount)
    }

    @objc(pageAtIndex:)
    func page(at index: Int) -> TestPDFPage? {
        precondition((0..<pageCount).contains(index))

        if pages[index] == nil {
            guard let page = document.page(at: index) else {
                return nil
            }
            pages[index] = TestPDFPage(pdfPage: page)
        }

        return pages[index]
    }
}

#endif // HAVE_PDFKIT
