/*
 * 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 "ImageData.h"
#include "ImageDecoderDirect2D.h"
#include "IntRect.h"
#include "MIMETypeRegistry.h"
#include "NotImplemented.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, ColorSpace 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;

    NativeImagePtr 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<GraphicsContext>(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, ColorSpace::SRGB, nullptr);
}

ImageBufferDirect2DBackend::ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, std::unique_ptr<PlatformContextDirect2D>&& platformContext, std::unique_ptr<GraphicsContext>&& context, NativeImagePtr&& 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();
}

NativeImagePtr 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;

    Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(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 image;
}

static NativeImagePtr 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
{
    NativeImagePtr image;
    if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes)
        image = copyNativeImage(copyBehavior);
    else
        image = copyNativeImage(DontCopyBackingStore);

    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;

    NativeImagePtr image = copyNativeImage(DontCopyBackingStore);
    return createBitmapImageAfterScalingIfNeeded(bitmapTarget.get(), WTFMove(image), internalSize(), resolutionScale(), preserveResolution);
}

NativeImagePtr 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);

    Checked<unsigned, RecordOverflow> 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.unsafeGet(), 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(m_resolutionScale, m_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(m_resolutionScale);

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

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

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

Vector<uint8_t> ImageBufferDirect2DBackend::toBGRAData() const
{
    notImplemented();
    return { };
}

RefPtr<ImageData> ImageBufferDirect2DBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const
{
    notImplemented();
    return ImageBufferBackend::getImageData(outputFormat, srcRect, nullptr);
}

void ImageBufferDirect2DBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint)
{
    notImplemented();
    ImageBufferBackend::putImageData(inputFormat, imageData, srcRect, destPoint, nullptr);
}

} // namespace WebCore

#endif // USE(DIRECT2D)
