/*
 * Copyright 2016 The Fuchsia Authors. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT HOLDERS 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 "WebView.h"

#include <WebCore/BackForwardController.h>
#include <WebCore/FocusController.h>
#include <WebCore/FrameLoadRequest.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/IntSize.h>
#include <WebCore/LogInitialization.h>
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
#include <WebCore/PageConfiguration.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/Settings.h>

#include <WebKit/fuchsia/WebCoreSupport/WebChromeClient.h>
#include <WebKit/fuchsia/WebCoreSupport/WebEditorClient.h>
#include <WebKit/fuchsia/WebCoreSupport/WebFrameLoaderClient.h>
#include <WebKit/fuchsia/WebCoreSupport/WebPlatformStrategies.h>

#include <WebStorageNamespaceProvider.h>

#include <iomanip>
#include <iostream>
#include <sstream>

#include <hid/hid.h>
#include <hid/usages.h>
#include <magenta/pixelformat.h>

using namespace std;
using namespace WebCore;

WebView::~WebView()
{
    if (m_cairoSurface) {
        cairo_surface_destroy(m_cairoSurface);
    }
    if (m_cairoContext) {
        cairo_destroy(m_cairoContext);
    }
    delete m_frameLoaderClient;
    delete m_chromeClient;
    delete m_page;
}

bool WebView::setup(unsigned char* pixelBuffer, int pixelFormat, size_t targetWidth, size_t targetHeight, size_t rowbytes)
{
    cairo_format_t format = CAIRO_FORMAT_INVALID;
    switch (pixelFormat) {
    case MX_PIXEL_FORMAT_RGB_565:
        format = CAIRO_FORMAT_RGB16_565;
        break;
    case MX_PIXEL_FORMAT_RGB_x888:
        format = CAIRO_FORMAT_RGB24;
        break;
    case MX_PIXEL_FORMAT_ARGB_8888:
        format = CAIRO_FORMAT_ARGB32;
        break;
    case MX_PIXEL_FORMAT_MONO_1:
        format = CAIRO_FORMAT_A1;
        break;
    case MX_PIXEL_FORMAT_MONO_8:
        format = CAIRO_FORMAT_A8;
        break;
    default:
        cout << "Unsupported pixel format " << pixelFormat << endl;
        return false;
    }

    m_cairoSurface = cairo_image_surface_create_for_data(pixelBuffer,
        format,
        targetWidth,
        targetHeight,
        rowbytes);
    cairo_status_t cairoStatus = cairo_surface_status(m_cairoSurface);
    if (cairoStatus != CAIRO_STATUS_SUCCESS) {
        cout << "cairo_image_surface_create_for_data failed: " << cairo_status_to_string(cairoStatus) << endl;
        return false;
    }

    m_cairoContext = cairo_create(m_cairoSurface);

    static std::once_flag initializeOnceFlag;
    std::call_once(initializeOnceFlag, [] {
        setenv("WEBKIT_DEBUG", "", 1);
        setenv("FONTCONFIG_FILE", "/system/fonts/fonts.conf", 1);
        setenv("FONTCONFIG_USE_MMAP", "0", 1);
        setenv("CURL_COOKIE_JAR_PATH", "/data/web_view/cookies.dat", 1);
        FcInit();
#if !LOG_DISABLED || !RELEASE_LOG_DISABLED
        WebCore::initializeLogChannelsIfNecessary();
#endif
        WTF::initializeThreading();
        WTF::initializeMainThread();
        WTF::RunLoop::initializeMainRunLoop();
        WebPlatformStrategies::initializeIfNecessary();
    });

    m_pageWidth = targetWidth;
    m_pageHeight = targetHeight;

    if (m_page == nullptr) {
        IntSize targetSize(targetWidth, targetHeight);
        PageConfiguration pageConfiguration(makeUniqueRef<WebKit::WebEditorClient>(), SocketProvider::create());
        fillWithEmptyClients(pageConfiguration);
        m_frameLoaderClient = new WebFrameLoaderClient(targetSize);
        pageConfiguration.loaderClientForMainFrame = m_frameLoaderClient;
        pageConfiguration.storageNamespaceProvider = WebStorageNamespaceProvider::create("/data");
        m_chromeClient = new WebChromeClient(targetSize);
        pageConfiguration.chromeClient = m_chromeClient;

        m_page = new Page(WTFMove(pageConfiguration));
        Settings& settings = m_page->settings();
        settings.setScriptEnabled(true);
        settings.setLoadsImagesAutomatically(true);
        settings.setLocalStorageEnabled(true);

        m_page->setIsInWindow(true);
        m_page->setGroupName("fuchsia_group");
        auto& mainFrame = m_page->mainFrame();
        m_frameLoaderClient->m_coreFrame = &mainFrame;

        mainFrame.tree().setName("fuchsia_group");
        mainFrame.init();
    }

    return true;
}

void WebView::setFileURL(const std::string& urlString)
{
    URL fileURL(URL::fileURLWithFileSystemPath(urlString.c_str()));
    setURLInternal(fileURL);
}

void WebView::setURL(const std::string& urlString)
{
    URL url(ParsedURLString, urlString.c_str());
    setURLInternal(url);
}

void WebView::setURLInternal(const WebCore::URL& url)
{
    ResourceRequest resourceRequest(url);

    auto& mainFrame = m_page->mainFrame();
    auto& loader = mainFrame.loader();
    FrameLoadRequest loadRequest(&mainFrame, resourceRequest, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
    loader.load(loadRequest);
}

void WebView::goBack()
{
    if (m_page) {
        m_page->backForward().goBack();
    }
}

void WebView::goForward()
{
    if (m_page) {
        m_page->backForward().goForward();
    }
}

void WebView::layoutAndPaint()
{
    Frame* frame = m_frameLoaderClient->m_coreFrame;
    if (frame) {
        GraphicsContext gc(m_cairoContext);
        FrameView* view = frame->view();
        view->updateLayoutAndStyleIfNeededRecursive();
        if (view->frame().contentRenderer()) {
            IntRect fullRect(0, 0, m_pageWidth, m_pageHeight);
            view->paint(gc, fullRect);
        }
        cairo_surface_flush(m_cairoSurface);
    }
}

void WebView::setFocused(bool focused)
{
    auto& mainFrame = m_page->mainFrame();
    m_page->focusController().setFocusedFrame(&mainFrame);
    m_page->focusController().setActive(focused);
    m_page->focusController().setFocused(focused);
}

void WebView::setVisible(bool visible)
{
    m_page->setIsVisible(visible);
}

void WebView::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
{
    auto& mainFrame = m_page->mainFrame();
    mainFrame.setPageAndTextZoomFactors(pageZoomFactor, textZoomFactor);
}

void WebView::handleMouseEvent(int x, int y, MouseEventKind eventType)
{
    auto& mainFrame = m_page->mainFrame();
    IntPoint mousePosition(x, y);
    auto now = std::chrono::steady_clock::now().time_since_epoch();
    auto timeSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
    if (eventType == kMouseDown) {
        WebCore::PlatformMouseEvent mouseEvent(mousePosition, mousePosition,
            WebCore::MouseButton::LeftButton, PlatformEvent::MousePressed,
            1, false, false, false, false, timeSinceEpoch, 0, SyntheticClickType::NoTap);
        mainFrame.eventHandler().handleMousePressEvent(mouseEvent);
    } else if (eventType == kMouseUp) {
        WebCore::PlatformMouseEvent mouseEvent(mousePosition, mousePosition,
            WebCore::MouseButton::LeftButton, PlatformEvent::MouseReleased,
            1, false, false, false, false, timeSinceEpoch, 0, SyntheticClickType::NoTap);
        mainFrame.eventHandler().handleMouseReleaseEvent(mouseEvent);
    } else {
        WebCore::PlatformMouseEvent mouseEvent(mousePosition, mousePosition,
            WebCore::MouseButton::NoButton, PlatformEvent::MouseMoved,
            0, false, false, false, false, timeSinceEpoch, 0, SyntheticClickType::NoTap);
        mainFrame.eventHandler().mouseMoved(mouseEvent);
    }
}

void WebView::handleKeyEvent(uint8_t keycode, uint8_t charValue, bool pressed)
{
    string identifier;

    if (keycode == HID_USAGE_KEY_LEFT_SHIFT || keycode == HID_USAGE_KEY_RIGHT_SHIFT) {
        fShift = pressed;
    } else if (keycode == HID_USAGE_KEY_LEFT_CTRL || keycode == HID_USAGE_KEY_RIGHT_CTRL) {
        fControl = pressed;
    }

    int rawModifiers = 0;
    if (fControl) {
        rawModifiers |= PlatformEvent::Modifiers::CtrlKey;
    }

    if (fShift) {
        rawModifiers |= PlatformEvent::Modifiers::ShiftKey;
    }

    if (charValue != 0) {
        ostringstream oss;
        oss << "U+" << hex << setw(4) << setfill('0') << (int)charValue;
        identifier = oss.str();
    } else if (keycode == HID_USAGE_KEY_BACKSPACE) {
        identifier = "U+0008";
        charValue = 9;
    } else if (keycode == HID_USAGE_KEY_TAB) {
        identifier = "U+0009";
        charValue = 8;
    }

    char charStr[2] = { static_cast<char>(charValue), 0 };

    auto now = std::chrono::steady_clock::now().time_since_epoch();
    auto timeSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
    WebCore::PlatformKeyboardEvent keyboardEvent(pressed ? WebCore::PlatformEvent::KeyDown : WebCore::PlatformEvent::KeyUp, charStr, charStr, identifier.c_str(),
        0, keycode, 0, false, false, false, (PlatformEvent::Modifiers)rawModifiers, timeSinceEpoch);
    auto& mainFrame = m_page->mainFrame();
    mainFrame.eventHandler().keyEvent(keyboardEvent);
}

void WebView::iterateEventLoop()
{
    RunLoop::iterate();
}
