/*
 * Copyright (C) 2018 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"
#import "EditableImageController.h"

#if HAVE(PENCILKIT)

#import "APIAttachment.h"
#import "EditableImageControllerMessages.h"
#import "PageClientImplIOS.h"
#import "PencilKitSPI.h"
#import "WKDrawingView.h"
#import "WebPageProxy.h"
#import "WebProcessProxy.h"
#import <WebCore/GraphicsLayer.h>
#import <wtf/RetainPtr.h>

#define MESSAGE_CHECK_VIEWID(embeddedViewID) MESSAGE_CHECK_BASE(m_editableImages.isValidKey(embeddedViewID), m_webPageProxy->process().connection())

namespace WebKit {

EditableImageController::EditableImageController(WebPageProxy& webPageProxy)
    : m_webPageProxy(makeWeakPtr(webPageProxy))
{
    if (auto* webPageProxy = m_webPageProxy.get())
        webPageProxy->process().addMessageReceiver(Messages::EditableImageController::messageReceiverName(), webPageProxy->webPageID(), *this);
}

EditableImageController::~EditableImageController()
{
    if (auto* webPageProxy = m_webPageProxy.get())
        webPageProxy->process().removeMessageReceiver(Messages::EditableImageController::messageReceiverName(), webPageProxy->webPageID());
}

EditableImage& EditableImageController::ensureEditableImage(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
{
    auto result = m_editableImages.ensure(embeddedViewID, [&] {
        std::unique_ptr<EditableImage> image = makeUnique<EditableImage>();
        image->drawingView = m_webPageProxy->pageClient().createDrawingView(embeddedViewID);
        return image;
    });
    return *result.iterator->value;
}

EditableImage* EditableImageController::editableImage(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
{
    auto drawingViewIter = m_editableImages.find(embeddedViewID);
    if (drawingViewIter == m_editableImages.end())
        return nil;
    return drawingViewIter->value.get();
}

void EditableImageController::didCreateEditableImage(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
{
    MESSAGE_CHECK_VIEWID(embeddedViewID);
    ensureEditableImage(embeddedViewID);
}

void EditableImageController::didDestroyEditableImage(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
{
    MESSAGE_CHECK_VIEWID(embeddedViewID);
    m_editableImages.remove(embeddedViewID);
}

void EditableImageController::associateWithAttachment(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID, const String& attachmentID)
{
    if (!m_webPageProxy)
        return;
    auto& page = *m_webPageProxy;

    MESSAGE_CHECK_VIEWID(embeddedViewID);
    page.registerAttachmentIdentifier(attachmentID);
    auto& attachment = *page.attachmentForIdentifier(attachmentID);

    auto& editableImage = ensureEditableImage(embeddedViewID);
    WeakObjCPtr<WKDrawingView> drawingView = editableImage.drawingView.get();
    editableImage.attachmentID = attachmentID;

    loadStrokesFromAttachment(editableImage, attachment);

    attachment.setFileWrapperGenerator([drawingView]() -> RetainPtr<NSFileWrapper> {
        if (!drawingView)
            return nil;
        NSData *data = [drawingView PNGRepresentation];
        if (!data)
            return nil;
        RetainPtr<NSFileWrapper> fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data]);
        [fileWrapper setPreferredFilename:@"drawing.png"];
        return fileWrapper;
    });
    attachment.setContentType("public.png");
}

void EditableImageController::loadStrokesFromAttachment(EditableImage& editableImage, const API::Attachment& attachment)
{
    ASSERT(attachment.identifier() == editableImage.attachmentID);
    NSFileWrapper *fileWrapper = attachment.fileWrapper();
    if (!fileWrapper.isRegularFile)
        return;
    [editableImage.drawingView loadDrawingFromPNGRepresentation:fileWrapper.regularFileContents];
}

void EditableImageController::invalidateAttachmentForEditableImage(WebCore::GraphicsLayer::EmbeddedViewID embeddedViewID)
{
    if (!m_webPageProxy)
        return;
    auto& page = *m_webPageProxy;

    auto editableImage = this->editableImage(embeddedViewID);
    if (!editableImage)
        return;

    auto attachment = page.attachmentForIdentifier(editableImage->attachmentID);
    if (!attachment)
        return;

    attachment->invalidateGeneratedFileWrapper();
}

WebPageProxy::ShouldUpdateAttachmentAttributes EditableImageController::willUpdateAttachmentAttributes(const API::Attachment& attachment)
{
    for (auto& editableImage : m_editableImages.values()) {
        if (editableImage->attachmentID != attachment.identifier())
            continue;

        loadStrokesFromAttachment(*editableImage, attachment);
        return WebPageProxy::ShouldUpdateAttachmentAttributes::No;
    }

    return WebPageProxy::ShouldUpdateAttachmentAttributes::Yes;
}

} // namespace WebKit

#undef MESSAGE_CHECK_VIEWID

#endif // HAVE(PENCILKIT)
