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

#include "config.h"
#include "InjectedBundleNodeHandle.h"

#include "InjectedBundleRangeHandle.h"
#include "ShareableBitmap.h"
#include "WebFrame.h"
#include "WebFrameLoaderClient.h"
#include "WebImage.h"
#include <JavaScriptCore/APICast.h>
#include <WebCore/Document.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/FrameView.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/HTMLFrameElement.h>
#include <WebCore/HTMLIFrameElement.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/HTMLNames.h>
#include <WebCore/HTMLSelectElement.h>
#include <WebCore/HTMLTableCellElement.h>
#include <WebCore/HTMLTextAreaElement.h>
#include <WebCore/IntRect.h>
#include <WebCore/JSNode.h>
#include <WebCore/Node.h>
#include <WebCore/Page.h>
#include <WebCore/Position.h>
#include <WebCore/Range.h>
#include <WebCore/RenderObject.h>
#include <WebCore/VisiblePosition.h>
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/WTFString.h>

namespace WebKit {
using namespace WebCore;
using namespace HTMLNames;

typedef HashMap<Node*, InjectedBundleNodeHandle*> DOMNodeHandleCache;

static DOMNodeHandleCache& domNodeHandleCache()
{
    static NeverDestroyed<DOMNodeHandleCache> cache;
    return cache;
}

RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(JSContextRef, JSObjectRef object)
{
    Node* node = JSNode::toWrapped(toJS(object)->vm(), toJS(object));
    return getOrCreate(node);
}

RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node* node)
{
    if (!node)
        return nullptr;

    return InjectedBundleNodeHandle::getOrCreate(*node);
}

Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node& node)
{
    DOMNodeHandleCache::AddResult result = domNodeHandleCache().add(&node, nullptr);
    if (!result.isNewEntry)
        return Ref<InjectedBundleNodeHandle>(*result.iterator->value);

    Ref<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::create(node);
    result.iterator->value = nodeHandle.ptr();
    return nodeHandle;
}

Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::create(Node& node)
{
    return adoptRef(*new InjectedBundleNodeHandle(node));
}

InjectedBundleNodeHandle::InjectedBundleNodeHandle(Node& node)
    : m_node(node)
{
}

InjectedBundleNodeHandle::~InjectedBundleNodeHandle()
{
    domNodeHandleCache().remove(m_node.ptr());
}

Node* InjectedBundleNodeHandle::coreNode()
{
    return m_node.ptr();
}

Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document()
{
    return getOrCreate(m_node->document());
}

// Additional DOM Operations
// Note: These should only be operations that are not exposed to JavaScript.

IntRect InjectedBundleNodeHandle::elementBounds()
{
    if (!is<Element>(m_node))
        return IntRect();

    return downcast<Element>(m_node.get()).boundsInRootViewSpace();
}
    
IntRect InjectedBundleNodeHandle::renderRect(bool* isReplaced)
{
    return m_node->pixelSnappedRenderRect(isReplaced);
}

static RefPtr<WebImage> imageForRect(FrameView* frameView, const IntRect& paintingRect, const Optional<float>& bitmapWidth, SnapshotOptions options)
{
    if (paintingRect.isEmpty())
        return nullptr;

    float bitmapScaleFactor;
    IntSize bitmapSize;
    if (bitmapWidth) {
        bitmapScaleFactor = bitmapWidth.value() / paintingRect.width();
        bitmapSize = roundedIntSize(FloatSize(bitmapWidth.value(), paintingRect.height() * bitmapScaleFactor));
    } else {
        bitmapScaleFactor = 1;
        bitmapSize = paintingRect.size();
    }

    float deviceScaleFactor = frameView->frame().page()->deviceScaleFactor();
    bitmapSize.scale(deviceScaleFactor);

    if (bitmapSize.isEmpty())
        return nullptr;

    auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
    if (!snapshot)
        return nullptr;

    auto graphicsContext = snapshot->bitmap().createGraphicsContext();
    if (!graphicsContext)
        return nullptr;

    graphicsContext->clearRect(IntRect(IntPoint(), bitmapSize));
    graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
    graphicsContext->scale(bitmapScaleFactor);
    graphicsContext->translate(-paintingRect.location());

    FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
    if (options & SnapshotOptionsExcludeSelectionHighlighting)
        shouldPaintSelection = FrameView::ExcludeSelection;

    auto paintBehavior = frameView->paintBehavior() | PaintBehavior::FlattenCompositingLayers | PaintBehavior::Snapshotting;
    if (options & SnapshotOptionsForceBlackText)
        paintBehavior.add(PaintBehavior::ForceBlackText);
    if (options & SnapshotOptionsForceWhiteText)
        paintBehavior.add(PaintBehavior::ForceWhiteText);

    auto oldPaintBehavior = frameView->paintBehavior();
    frameView->setPaintBehavior(paintBehavior);
    frameView->paintContentsForSnapshot(*graphicsContext.get(), paintingRect, shouldPaintSelection, FrameView::DocumentCoordinates);
    frameView->setPaintBehavior(oldPaintBehavior);

    return snapshot;
}

RefPtr<WebImage> InjectedBundleNodeHandle::renderedImage(SnapshotOptions options, bool shouldExcludeOverflow, const Optional<float>& bitmapWidth)
{
    Frame* frame = m_node->document().frame();
    if (!frame)
        return nullptr;

    FrameView* frameView = frame->view();
    if (!frameView)
        return nullptr;

    m_node->document().updateLayout();

    RenderObject* renderer = m_node->renderer();
    if (!renderer)
        return nullptr;

    IntRect paintingRect;
    if (shouldExcludeOverflow)
        paintingRect = renderer->absoluteBoundingBoxRectIgnoringTransforms();
    else {
        LayoutRect topLevelRect;
        paintingRect = snappedIntRect(renderer->paintingRootRect(topLevelRect));
    }

    frameView->setNodeToDraw(m_node.ptr());
    auto image = imageForRect(frameView, paintingRect, bitmapWidth, options);
    frameView->setNodeToDraw(0);

    return image;
}

RefPtr<InjectedBundleRangeHandle> InjectedBundleNodeHandle::visibleRange()
{
    VisiblePosition start = firstPositionInNode(m_node.ptr());
    VisiblePosition end = lastPositionInNode(m_node.ptr());

    RefPtr<Range> range = makeRange(start, end);
    return InjectedBundleRangeHandle::getOrCreate(range.get());
}

void InjectedBundleNodeHandle::setHTMLInputElementValueForUser(const String& value)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setValueForUser(value);
}

void InjectedBundleNodeHandle::setHTMLInputElementSpellcheckEnabled(bool enabled)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setSpellcheckDisabledExceptTextReplacement(!enabled);
}

bool InjectedBundleNodeHandle::isHTMLInputElementAutoFilled() const
{
    if (!is<HTMLInputElement>(m_node))
        return false;
    
    return downcast<HTMLInputElement>(m_node.get()).isAutoFilled();
}

bool InjectedBundleNodeHandle::isHTMLInputElementAutoFilledAndViewable() const
{
    if (!is<HTMLInputElement>(m_node))
        return false;

    return downcast<HTMLInputElement>(m_node.get()).isAutoFilledAndViewable();
}

void InjectedBundleNodeHandle::setHTMLInputElementAutoFilled(bool filled)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setAutoFilled(filled);
}

void InjectedBundleNodeHandle::setHTMLInputElementAutoFilledAndViewable(bool autoFilledAndViewable)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setAutoFilledAndViewable(autoFilledAndViewable);
}

bool InjectedBundleNodeHandle::isHTMLInputElementAutoFillButtonEnabled() const
{
    if (!is<HTMLInputElement>(m_node))
        return false;
    
    return downcast<HTMLInputElement>(m_node.get()).autoFillButtonType() != AutoFillButtonType::None;
}

void InjectedBundleNodeHandle::setHTMLInputElementAutoFillButtonEnabled(AutoFillButtonType autoFillButtonType)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setShowAutoFillButton(autoFillButtonType);
}

AutoFillButtonType InjectedBundleNodeHandle::htmlInputElementAutoFillButtonType() const
{
    if (!is<HTMLInputElement>(m_node))
        return AutoFillButtonType::None;
    return downcast<HTMLInputElement>(m_node.get()).autoFillButtonType();
}

AutoFillButtonType InjectedBundleNodeHandle::htmlInputElementLastAutoFillButtonType() const
{
    if (!is<HTMLInputElement>(m_node))
        return AutoFillButtonType::None;
    return downcast<HTMLInputElement>(m_node.get()).lastAutoFillButtonType();
}

bool InjectedBundleNodeHandle::isAutoFillAvailable() const
{
    if (!is<HTMLInputElement>(m_node))
        return false;

    return downcast<HTMLInputElement>(m_node.get()).isAutoFillAvailable();
}

void InjectedBundleNodeHandle::setAutoFillAvailable(bool autoFillAvailable)
{
    if (!is<HTMLInputElement>(m_node))
        return;

    downcast<HTMLInputElement>(m_node.get()).setAutoFillAvailable(autoFillAvailable);
}

IntRect InjectedBundleNodeHandle::htmlInputElementAutoFillButtonBounds()
{
    if (!is<HTMLInputElement>(m_node))
        return IntRect();

    auto autoFillButton = downcast<HTMLInputElement>(m_node.get()).autoFillButtonElement();
    if (!autoFillButton)
        return IntRect();

    return autoFillButton->boundsInRootViewSpace();
}

bool InjectedBundleNodeHandle::htmlInputElementLastChangeWasUserEdit()
{
    if (!is<HTMLInputElement>(m_node))
        return false;

    return downcast<HTMLInputElement>(m_node.get()).lastChangeWasUserEdit();
}

bool InjectedBundleNodeHandle::htmlTextAreaElementLastChangeWasUserEdit()
{
    if (!is<HTMLTextAreaElement>(m_node))
        return false;

    return downcast<HTMLTextAreaElement>(m_node.get()).lastChangeWasUserEdit();
}

bool InjectedBundleNodeHandle::isTextField() const
{
    if (!is<HTMLInputElement>(m_node))
        return false;

    return downcast<HTMLInputElement>(m_node.get()).isTextField();
}

bool InjectedBundleNodeHandle::isSelectElement() const
{
    return is<HTMLSelectElement>(m_node);
}

RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::htmlTableCellElementCellAbove()
{
    if (!is<HTMLTableCellElement>(m_node))
        return nullptr;

    return getOrCreate(downcast<HTMLTableCellElement>(m_node.get()).cellAbove());
}

RefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame()
{
    if (!m_node->isDocumentNode())
        return nullptr;

    Frame* frame = downcast<Document>(m_node.get()).frame();
    if (!frame)
        return nullptr;

    return WebFrame::fromCoreFrame(*frame);
}

RefPtr<WebFrame> InjectedBundleNodeHandle::htmlFrameElementContentFrame()
{
    if (!is<HTMLFrameElement>(m_node))
        return nullptr;

    Frame* frame = downcast<HTMLFrameElement>(m_node.get()).contentFrame();
    if (!frame)
        return nullptr;

    return WebFrame::fromCoreFrame(*frame);
}

RefPtr<WebFrame> InjectedBundleNodeHandle::htmlIFrameElementContentFrame()
{
    if (!is<HTMLIFrameElement>(m_node))
        return nullptr;

    Frame* frame = downcast<HTMLIFrameElement>(m_node.get()).contentFrame();
    if (!frame)
        return nullptr;

    return WebFrame::fromCoreFrame(*frame);
}

} // namespace WebKit
