/*
 * Copyright (C) 2020 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. ``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
 * 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.
 */

#include "config.h"
#include "ImageBufferDirect2DBackend.h"

#if USE(DIRECT2D)

#include "BitmapImage.h"
#include "COMPtr.h"
#include "Direct2DUtilities.h"
#include "GraphicsContext.h"
#include "ImageDecoderDirect2D.h"
#include "IntRect.h"
#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
#include "PixelBuffer.h"
#include "PlatformContextDirect2D.h"
#include <d2d1_1.h>
#include <math.h>
#include <wincodec.h>
#include <wtf/Assertions.h>
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferDirect2DBackend);

std::unique_ptr<ImageBufferDirect2DBackend> ImageBufferDirect2DBackend::create(const FloatSize& size, float resolutionScale, DestinationColorSpace colorSpace, const HostWindow* hostWindow)
{
    IntSize backendSize = calculateBackendSize(size, resolutionScale);
    if (backendSize.isEmpty())
        return nullptr;

    auto* platformContext = targetContext ? targetContext->platformContext() : nullptr;
    auto* renderTarget = platformContext ? platformContext->renderTarget() : nullptr;

    if (!renderTarget)
        renderTarget = GraphicsContext::defaultRenderTarget();

    auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(size, renderTarget, resolutionScale);
    if (!bitmapContext)
        return;

    PlatformImagePtr bitmap;
    HRESULT hr = bitmapContext->GetBitmap(&bitmap);
    if (!SUCCEEDED(hr))
        return;

    auto platformContext = makeUnique<PlatformContextDirect2D>(bitmapContext.get(), [this]() {
        m_data.loadDataToBitmapIfNeeded();
    }, [this]() {
        m_data.markBufferOutOfSync();
    });

    if (!platformContext)
        return nullptr;

    auto context = makeUnique<GraphicsContextDirect2D>(platformContext.get(), GraphicsContext::BitmapRenderingContextType::GPUMemory);
    if (!context)
        return nullptr;

    return std::unique_ptr<ImageBufferDirect2DBackend>(new ImageBufferDirect2DBackend(size, backendSize, resolutionScale, colorSpace, WTFMove(platformContext), WTFMove(context), WTFMove(bitmap)));
}

std::unique_ptr<ImageBufferDirect2DBackend> ImageBufferDirect2DBackend::create(const FloatSize& size, const GraphicsContext& context)
{
    return ImageBufferDirect2DBackend::create(size, 1, DestinationColorSpace::SRGB, nullptr);
}

ImageBufferDirect2DBackend::ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, DestinationColorSpace colorSpace, std::unique_ptr<PlatformContextDirect2D>&& platformContext, std::unique_ptr<GraphicsContext>&& context, PlatformImagePtr&& bitmap)
    : ImageBufferCGBackend(logicalSize, backendSize, resolutionScale, colorSpace)
    , m_platformContext(WTFMove(platformContext))
    , m_context(WTFMove(context))
    , m_bitmap(WTFMove(bitmap))
{
}

GraphicsContext& ImageBufferDirect2DBackend::context() const
{
    return *m_context;
}

void ImageBufferDirect2DBackend::flushContext()
{
    context().flush();
}

RefPtr<NativeImage> ImageBufferDirect2DBackend::copyNativeImage(BackingStoreCopy copyBehavior) const
{
    COMPtr<ID2D1BitmapRenderTarget> bitmapTarget;
    HRESULT hr = context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget);
    if (!SUCCEEDED(hr))
        return nullptr;

    COMPtr<ID2D1Bitmap> image;
    hr = bitmapTarget->GetBitmap(&image);
    ASSERT(SUCCEEDED(hr));

    // FIXME: m_data.data is nullptr even when asking to copy backing store leading to test failures.
    if (copyBehavior == CopyBackingStore && m_data.data.isEmpty())
        copyBehavior = DontCopyBackingStore;

    CheckedSize numBytes = CheckedUint32(m_data.backingStoreSize.height()) * m_data.bytesPerRow;
    if (numBytes.hasOverflowed())
        return nullptr;

    if (copyBehavior == CopyBackingStore) {
        D2D1_RECT_U backingStoreDimenstions = IntRect(IntPoint(), m_data.backingStoreSize);
        image->CopyFromMemory(&backingStoreDimenstions, m_data.data.data(), 32);

    }

    return NativeImage::create(WTFMove(image));
}

static PlatformImagePtr createCroppedImageIfNecessary(ID2D1BitmapRenderTarget* bitmapTarget, ID2D1Bitmap* image, const IntSize& bounds)
{
    FloatSize imageSize = image ? nativeImageSize(image) : FloatSize();

    if (image && (static_cast<size_t>(imageSize.width()) != static_cast<size_t>(bounds.width()) || static_cast<size_t>(imageSize.height()) != static_cast<size_t>(bounds.height()))) {
        COMPtr<ID2D1Bitmap> croppedBitmap = Direct2D::createBitmap(bitmapTarget, bounds);
        if (croppedBitmap) {
            auto sourceRect = D2D1::RectU(0, 0, bounds.width(), bounds.height());
            HRESULT hr = croppedBitmap->CopyFromBitmap(nullptr, image, &sourceRect);
            if (SUCCEEDED(hr))
                return croppedBitmap;
        }
    }

    return image;
}

static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(ID2D1BitmapRenderTarget* bitmapTarget, COMPtr<ID2D1Bitmap>&& image, IntSize internalSize, float resolutionScale, PreserveResolution preserveResolution)
{
    if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes)
        image = createCroppedImageIfNecessary(bitmapTarget, image.get(), internalSize);
    else {
        // FIXME: Need to implement scaled version
        notImplemented();
    }

    if (!image)
        return nullptr;

    return BitmapImage::create(WTFMove(image));
}

RefPtr<Image> ImageBufferDirect2DBackend::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const
{
    PlatformImagePtr image;
    if (resolutionScale() == 1 || preserveResolution == PreserveResolution::Yes)
        image = copyNativeImage(copyBehavior)->platformImage();
    else
        image = copyNativeImage(DontCopyBackingStore)->platformImage();

    auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext());
    return createBitmapImageAfterScalingIfNeeded(bitmapTarget, WTFMove(image), internalSize(), resolutionScale(), preserveResolution);
}

RefPtr<Image> ImageBufferDirect2DBackend::sinkIntoImage(PreserveResolution preserveResolution)
{
    COMPtr<ID2D1BitmapRenderTarget> bitmapTarget;
    HRESULT hr = context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget);
    if (!SUCCEEDED(hr))
        return nullptr;

    PlatformImagePtr image = copyNativeImage(DontCopyBackingStore)->platformImage();
    return createBitmapImageAfterScalingIfNeeded(bitmapTarget.get(), WTFMove(image), internalSize(), resolutionScale(), preserveResolution);
}

PlatformImagePtr ImageBufferDirect2DBackend::compatibleBitmap(ID2D1RenderTarget* renderTarget)
{
    loadDataToBitmapIfNeeded();

    if (!renderTarget)
        return bitmap;

    if (m_platformContext->renderTarget() == renderTarget) {
        COMPtr<ID2D1BitmapRenderTarget> bitmapTarget(Query, renderTarget);
        if (bitmapTarget) {
            COMPtr<ID2D1Bitmap> backingBitmap;
            if (SUCCEEDED(bitmapTarget->GetBitmap(&backingBitmap))) {
                if (backingBitmap != m_bitmap)
                    return bitmap;

                // We can't draw an ID2D1Bitmap to itself. Must return a copy.
                COMPtr<ID2D1Bitmap> copiedBitmap;
                if (SUCCEEDED(renderTarget->CreateBitmap(bitmap->GetPixelSize(), Direct2D::bitmapProperties(), &copiedBitmap))) {
                    if (SUCCEEDED(copiedBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr)))
                        return copiedBitmap;
                }
            }
        }
    }

    auto size = m_bitmap->GetPixelSize();
    ASSERT(size.height && size.width);

    CheckedUint32 numBytes = size.width * size.height * 4;
    if (numBytes.hasOverflowed())
        return nullptr;

    // Copy the bits from current renderTarget to the output target.
    // We cannot access the data backing an IWICBitmap while an active draw session is open.
    context->endDraw();

    COMPtr<ID2D1DeviceContext> sourceDeviceContext = m_platformContext->deviceContext();
    if (!sourceDeviceContext)
        return nullptr;

    COMPtr<ID2D1Bitmap1> sourceCPUBitmap;
    D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat());
    HRESULT hr = sourceDeviceContext->CreateBitmap(m_bitmap->GetPixelSize(), nullptr, bytesPerRow, bitmapProperties, &sourceCPUBitmap);
    if (!SUCCEEDED(hr))
        return nullptr;

    if (!sourceCPUBitmap)
        return nullptr;

    hr = sourceCPUBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr);
    if (!SUCCEEDED(hr))
        return nullptr;

    D2D1_MAPPED_RECT mappedSourceData;
    hr = sourceCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedSourceData);
    if (!SUCCEEDED(hr))
        return nullptr;

    COMPtr<ID2D1DeviceContext> targetDeviceContext;
    hr = renderTarget->QueryInterface(&targetDeviceContext);
    ASSERT(SUCCEEDED(hr));

    COMPtr<ID2D1Bitmap> compatibleBitmap;
    hr = targetDeviceContext->CreateBitmap(bitmap->GetPixelSize(), mappedSourceData.bits, mappedSourceData.pitch, Direct2D::bitmapProperties(), &compatibleBitmap);
    if (!SUCCEEDED(hr))
        return nullptr;

    hr = sourceCPUBitmap->Unmap();
    ASSERT(SUCCEEDED(hr));

    context->beginDraw();

    return compatibleBitmap;
}

void ImageBufferDirect2DBackend::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
{
    FloatRect adjustedSrcRect = srcRect;
    adjustedSrcRect.scale(resolutionScale());

    auto compatibleBitmap = compatibleBitmap(destContext.platformContext()->renderTarget());

    FloatSize currentImageSize = nativeImageSize(compatibleBitmap);
    if (currentImageSize.isZero())
        return;

    destContext.drawNativeImage(compatibleBitmap, currentImageSize, destRect, adjustedSrcRect, options);
}

void ImageBufferDirect2DBackend::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
{
    FloatRect adjustedSrcRect = srcRect;
    adjustedSrcRect.scale(resolutionScale());

    if (auto image = copyImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore))
        image->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options);
}

void ImageBufferDirect2DBackend::clipToMask(GraphicsContext&, const FloatRect&)
{
    notImplemented();
}

String ImageBufferDirect2DBackend::toDataURL(const String&, std::optional<double>, PreserveResolution) const
{
    notImplemented();
    return "data:,"_s;
}

Vector<uint8_t> ImageBufferDirect2DBackend::toData(const String& mimeType, std::optional<double> quality) const
{
    notImplemented();
    return { };
}

std::optional<PixelBuffer> ImageBufferDirect2DBackend::getPixelBuffer(const PixelBufferFormat& outputFormat, const IntRect& srcRect) const
{
    notImplemented();
    return ImageBufferBackend::getPixelBuffer(outputFormat, srcRect, nullptr);
}

void ImageBufferDirect2DBackend::putPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
{
    notImplemented();
    ImageBufferBackend::putPixelBuffer(pixelBuffer, srcRect, destPoint, destFormat, nullptr);
}

} // namespace WebCore

#endif // USE(DIRECT2D)
