/*
 * Copyright (C) 2006-2010, 2014, 2015 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "WebInspectorClient.h"

#include "WebInspectorDelegate.h"
#include "WebKit.h"
#include "WebMutableURLRequest.h"
#include "WebNodeHighlight.h"
#include "WebView.h"
#include <JavaScriptCore/InspectorAgentBase.h>
#include <WebCore/BString.h>
#include <WebCore/CertificateInfo.h>
#include <WebCore/Element.h>
#include <WebCore/FloatRect.h>
#include <WebCore/FrameView.h>
#include <WebCore/InspectorController.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
#include <WebCore/RenderObject.h>
#include <WebCore/WebCoreBundleWin.h>
#include <WebCore/WindowMessageBroadcaster.h>
#include <wchar.h>
#include <wtf/RetainPtr.h>
#include <wtf/text/StringConcatenate.h>

using namespace WebCore;

static LPCTSTR kWebInspectorWindowClassName = TEXT("WebInspectorWindowClass");
static ATOM registerWindowClass();
static LPCTSTR kWebInspectorPointerProp = TEXT("WebInspectorPointer");

static const IntRect& defaultWindowRect()
{
    static IntRect rect(60, 200, 750, 650);
    return rect;
}

WebInspectorClient::WebInspectorClient(WebView* webView)
    : m_inspectedWebView(webView)
    , m_frontendPage(0)
{
    ASSERT(m_inspectedWebView);
    m_inspectedWebView->viewWindow(&m_inspectedWebViewHandle);
}

WebInspectorClient::~WebInspectorClient()
{
}

void WebInspectorClient::inspectedPageDestroyed()
{
    delete this;
}

Inspector::FrontendChannel* WebInspectorClient::openLocalFrontend(InspectorController* inspectorController)
{
    registerWindowClass();

    HWND frontendHwnd = ::CreateWindowEx(0, kWebInspectorWindowClassName, 0, WS_OVERLAPPEDWINDOW,
        defaultWindowRect().x(), defaultWindowRect().y(), defaultWindowRect().width(), defaultWindowRect().height(),
        0, 0, 0, 0);

    if (!frontendHwnd)
        return 0;

    COMPtr<WebView> frontendWebView(AdoptCOM, WebView::createInstance());

    if (FAILED(frontendWebView->setHostWindow(frontendHwnd)))
        return 0;

    RECT rect;
    GetClientRect(frontendHwnd, &rect);
    if (FAILED(frontendWebView->initWithFrame(rect, 0, 0)))
        return 0;

    COMPtr<WebInspectorDelegate> delegate(AdoptCOM, WebInspectorDelegate::createInstance());
    if (FAILED(frontendWebView->setUIDelegate(delegate.get())))
        return 0;

    // Keep preferences separate from the rest of the client, making sure we are using expected preference values.
    // FIXME: It's crazy that we have to do this song and dance to end up with
    // a private WebPreferences object, even within WebKit. We should make this
    // process simpler, and consider whether we can make it simpler for WebKit
    // clients as well.
    COMPtr<WebPreferences> tempPreferences(AdoptCOM, WebPreferences::createInstance());
    COMPtr<IWebPreferences> iPreferences;
    if (FAILED(tempPreferences->initWithIdentifier(BString(L"WebInspectorPreferences"), &iPreferences)))
        return 0;
    COMPtr<WebPreferences> preferences(Query, iPreferences);
    if (!preferences)
        return 0;
    if (FAILED(preferences->setAutosaves(FALSE)))
        return 0;
    if (FAILED(preferences->setLoadsImagesAutomatically(TRUE)))
        return 0;
    if (FAILED(preferences->setAuthorAndUserStylesEnabled(TRUE)))
        return 0;
    if (FAILED(preferences->setAllowFileAccessFromFileURLs(TRUE)))
        return 0;
    if (FAILED(preferences->setAllowUniversalAccessFromFileURLs(TRUE)))
        return 0;
    if (FAILED(preferences->setAllowsAnimatedImages(TRUE)))
        return 0;
    if (FAILED(preferences->setLoadsImagesAutomatically(TRUE)))
        return 0;
    if (FAILED(preferences->setPlugInsEnabled(FALSE)))
        return 0;
    if (FAILED(preferences->setJavaEnabled(FALSE)))
        return 0;
    if (FAILED(preferences->setUserStyleSheetEnabled(FALSE)))
        return 0;
    if (FAILED(preferences->setTabsToLinks(FALSE)))
        return 0;
    if (FAILED(preferences->setMinimumFontSize(0)))
        return 0;
    if (FAILED(preferences->setMinimumLogicalFontSize(9)))
        return 0;
    if (FAILED(preferences->setFixedFontFamily(BString(L"Courier New"))))
        return 0;
    if (FAILED(preferences->setDefaultFixedFontSize(13)))
        return 0;

    if (FAILED(frontendWebView->setPreferences(preferences.get())))
        return 0;

    frontendWebView->setProhibitsMainFrameScrolling(TRUE);

    HWND frontendWebViewHwnd;
    if (FAILED(frontendWebView->viewWindow(&frontendWebViewHwnd)))
        return 0;

    COMPtr<WebMutableURLRequest> request(AdoptCOM, WebMutableURLRequest::createInstance());

    RetainPtr<CFURLRef> htmlURLRef = adoptCF(CFBundleCopyResourceURL(webKitBundle(), CFSTR("Main"), CFSTR("html"), CFSTR("WebInspectorUI")));
    if (!htmlURLRef)
        return 0;

    CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get());
    if (FAILED(request->initWithURL(BString(urlStringRef), WebURLRequestUseProtocolCachePolicy, 60)))
        return 0;

    if (FAILED(frontendWebView->topLevelFrame()->loadRequest(request.get())))
        return 0;

    m_frontendPage = core(frontendWebView.get());
    m_frontendClient = makeUnique<WebInspectorFrontendClient>(m_inspectedWebView, m_inspectedWebViewHandle, frontendHwnd, frontendWebView, frontendWebViewHwnd, this, createFrontendSettings());
    m_frontendPage->inspectorController().setInspectorFrontendClient(m_frontendClient.get());
    m_frontendHandle = frontendHwnd;
    return this;
}

void WebInspectorClient::bringFrontendToFront()
{
    m_frontendClient->bringToFront();
}

void WebInspectorClient::highlight()
{
    bool creatingHighlight = !m_highlight;

    if (creatingHighlight)
        m_highlight = makeUnique<WebNodeHighlight>(m_inspectedWebView);

    if (m_highlight->isShowing())
        m_highlight->update();
    else
        m_highlight->setShowsWhileWebViewIsVisible(true);

    if (creatingHighlight && IsWindowVisible(m_frontendHandle))
        m_highlight->placeBehindWindow(m_frontendHandle);
}

void WebInspectorClient::hideHighlight()
{
    if (m_highlight)
        m_highlight->setShowsWhileWebViewIsVisible(false);
}

void WebInspectorClient::updateHighlight()
{
    if (m_highlight && m_highlight->isShowing())
        m_highlight->update();
}

void WebInspectorClient::releaseFrontend()
{
    m_frontendClient = nullptr;
    m_frontendPage = 0;
    m_frontendHandle = 0;
}

WebInspectorFrontendClient::WebInspectorFrontendClient(WebView* inspectedWebView, HWND inspectedWebViewHwnd, HWND frontendHwnd, const COMPtr<WebView>& frontendWebView, HWND frontendWebViewHwnd, WebInspectorClient* inspectorClient, std::unique_ptr<Settings> settings)
    : InspectorFrontendClientLocal(&inspectedWebView->page()->inspectorController(),  core(frontendWebView.get()), WTFMove(settings))
    , m_inspectedWebView(inspectedWebView)
    , m_inspectedWebViewHwnd(inspectedWebViewHwnd)
    , m_frontendHwnd(frontendHwnd)
    , m_inspectorClient(inspectorClient)
    , m_frontendWebView(frontendWebView)
    , m_frontendWebViewHwnd(frontendWebViewHwnd)
    , m_attached(false)
    , m_destroyingInspectorView(false)
{
    ::SetProp(frontendHwnd, kWebInspectorPointerProp, reinterpret_cast<HANDLE>(this));
    // FIXME: Implement window size/position save/restore
#if 0
    [self setWindowFrameAutosaveName:@"Web Inspector"];
#endif
}

WebInspectorFrontendClient::~WebInspectorFrontendClient()
{
    destroyInspectorView();
}

void WebInspectorFrontendClient::frontendLoaded()
{
    InspectorFrontendClientLocal::frontendLoaded();

    if (m_attached)
        restoreAttachedWindowHeight();

    setAttachedWindow(m_attached ? DockSide::Bottom : DockSide::Undocked);
}

String WebInspectorFrontendClient::localizedStringsURL()
{
    RetainPtr<CFURLRef> url = adoptCF(CFBundleCopyResourceURL(webKitBundle(), CFSTR("localizedStrings"), CFSTR("js"), CFSTR("WebInspectorUI")));
    if (!url)
        url = adoptCF(CFBundleCopyResourceURL(webKitBundle(), CFSTR("localizedStrings"), CFSTR("js"), 0));

    if (!url)
        return String();

    return CFURLGetString(url.get());
}

void WebInspectorFrontendClient::bringToFront()
{
    showWindowWithoutNotifications();
}

void WebInspectorFrontendClient::closeWindow()
{
    destroyInspectorView();
}

void WebInspectorFrontendClient::reopen()
{
    destroyInspectorView();

    if (Page* inspectedPage = m_inspectedWebView->page())
        inspectedPage->inspectorController().show();
}

void WebInspectorFrontendClient::resetState()
{
    InspectorFrontendClientLocal::resetState();

    m_inspectorClient->deleteInspectorStartsAttached();
    m_inspectorClient->deleteInspectorAttachDisabled();
}

void WebInspectorFrontendClient::attachWindow(DockSide)
{
    if (m_attached)
        return;

    m_inspectorClient->setInspectorStartsAttached(true);

    closeWindowWithoutNotifications();
    // We need to set the attached window's height before we actually attach the window.
    // Make sure that m_attached is true so that calling setAttachedWindowHeight from restoreAttachedWindowHeight doesn't return early.
    m_attached = true;
    // Immediately after calling showWindowWithoutNotifications(), the parent frameview's visibleHeight incorrectly returns 0 always (Windows only).
    // We are expecting this value to be just the height of the parent window when we call restoreAttachedWindowHeight, which it is before
    // calling showWindowWithoutNotifications().
    restoreAttachedWindowHeight();
    showWindowWithoutNotifications();
}

void WebInspectorFrontendClient::detachWindow()
{
    if (!m_attached)
        return;

    m_inspectorClient->setInspectorStartsAttached(false);

    closeWindowWithoutNotifications();
    showWindowWithoutNotifications();
}

void WebInspectorFrontendClient::setAttachedWindowHeight(unsigned height)
{
    if (!m_attached)
        return;

    HWND hostWindow;
    if (!SUCCEEDED(m_inspectedWebView->hostWindow(&hostWindow)))
        return;

    RECT hostWindowRect;
    GetClientRect(hostWindow, &hostWindowRect);

    RECT frontendRect;
    GetClientRect(m_frontendWebViewHwnd, &frontendRect);

    RECT inspectedRect;
    GetClientRect(m_inspectedWebViewHwnd, &inspectedRect);

    int hostWindowHeight = hostWindowRect.bottom;
    int webViewWidth = inspectedRect.right - inspectedRect.left;
    int webViewHeight = frontendRect.bottom + inspectedRect.bottom;
    height *= m_inspectedWebView->deviceScaleFactor();

    SetWindowPos(m_frontendWebViewHwnd, 0, 0, hostWindowHeight - height, webViewWidth, height, SWP_NOZORDER);

    // We want to set the inspected web view height to the totalHeight, because the height adjustment
    // of the inspected web view happens in onWebViewWindowPosChanging, not here.
    SetWindowPos(m_inspectedWebViewHwnd, 0, 0, hostWindowHeight - webViewHeight, webViewWidth, webViewHeight, SWP_NOZORDER);

    RedrawWindow(m_frontendWebViewHwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
    RedrawWindow(m_inspectedWebViewHwnd, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
}

void WebInspectorFrontendClient::setAttachedWindowWidth(unsigned)
{
    notImplemented();
}

void WebInspectorFrontendClient::setSheetRect(const FloatRect&)
{
    notImplemented();
}

void WebInspectorFrontendClient::inspectedURLChanged(const String& newURL)
{
    m_inspectedURL = newURL;
    updateWindowTitle();
}

void WebInspectorFrontendClient::showCertificate(const CertificateInfo&)
{
    notImplemented();
}

void WebInspectorFrontendClient::closeWindowWithoutNotifications()
{
    if (!m_frontendHwnd)
        return;

    if (!m_attached) {
        ShowWindow(m_frontendHwnd, SW_HIDE);
        return;
    }

    ASSERT(m_frontendWebView);
    ASSERT(m_inspectedWebViewHwnd);
    ASSERT(!IsWindowVisible(m_frontendHwnd));

    // Remove the Inspector's WebView from the inspected WebView's parent window.
    WindowMessageBroadcaster::removeListener(m_inspectedWebViewHwnd, this);

    m_attached = false;

    m_frontendWebView->setHostWindow(m_frontendHwnd);

    // Make sure everything has the right size/position.
    HWND hostWindow;
    if (SUCCEEDED(m_inspectedWebView->hostWindow(&hostWindow)))
        SendMessage(hostWindow, WM_SIZE, 0, 0);
}

void WebInspectorFrontendClient::showWindowWithoutNotifications()
{
    if (!m_frontendHwnd)
        return;

    ASSERT(m_frontendWebView);
    ASSERT(m_inspectedWebViewHwnd);

    bool shouldAttach = false;
    if (m_attached)
        shouldAttach = true;
    else {
        // If no preference is set - default to an attached window. This is important for inspector LayoutTests.
        // FIXME: This flag can be fetched directly from the flags storage.
        shouldAttach = m_inspectorClient->inspectorStartsAttached();

        if (shouldAttach && !canAttachWindow())
            shouldAttach = false;
    }

    if (!shouldAttach) {
        // Put the Inspector's WebView inside our window and show it.
        m_frontendWebView->setHostWindow(m_frontendHwnd);
        SendMessage(m_frontendHwnd, WM_SIZE, 0, 0);
        updateWindowTitle();

        SetWindowPos(m_frontendHwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
        return;
    }

    // Put the Inspector's WebView inside the inspected WebView's parent window.
    WindowMessageBroadcaster::addListener(m_inspectedWebViewHwnd, this);

    HWND hostWindow;
    if (FAILED(m_inspectedWebView->hostWindow(&hostWindow)))
        return;

    m_frontendWebView->setHostWindow(hostWindow);

    // Then hide our own window.
    ShowWindow(m_frontendHwnd, SW_HIDE);

    m_attached = true;

    // Make sure everything has the right size/position.
    SendMessage(hostWindow, WM_SIZE, 0, 0);
    m_inspectorClient->updateHighlight();
}

void WebInspectorFrontendClient::destroyInspectorView()
{
    if (m_destroyingInspectorView)
        return;
    m_destroyingInspectorView = true;

    if (Page* frontendPage = this->frontendPage())
        frontendPage->inspectorController().setInspectorFrontendClient(nullptr);
    if (Page* inspectedPage = m_inspectedWebView->page())
        inspectedPage->inspectorController().disconnectFrontend(*m_inspectorClient);

    m_inspectorClient->releaseFrontend();

    closeWindowWithoutNotifications();

    m_inspectorClient->updateHighlight();

    ::DestroyWindow(m_frontendHwnd);
}

void WebInspectorFrontendClient::updateWindowTitle()
{
    String title = makeString("Web Inspector ", static_cast<UChar>(0x2014), ' ', m_inspectedURL);
    ::SetWindowText(m_frontendHwnd, title.wideCharacters().data());
}

LRESULT WebInspectorFrontendClient::onGetMinMaxInfo(WPARAM, LPARAM lParam)
{
    MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam);
    POINT size = {400, 400};
    info->ptMinTrackSize = size;

    return 0;
}

LRESULT WebInspectorFrontendClient::onSize(WPARAM, LPARAM)
{
    RECT rect;
    ::GetClientRect(m_frontendHwnd, &rect);

    ::SetWindowPos(m_frontendWebViewHwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);

    return 0;
}

LRESULT WebInspectorFrontendClient::onClose(WPARAM, LPARAM)
{
    ::ShowWindow(m_frontendHwnd, SW_HIDE);
    closeWindow();

    return 0;
}

LRESULT WebInspectorFrontendClient::onSetFocus()
{
    SetFocus(m_frontendWebViewHwnd);
    return 0;
}

void WebInspectorFrontendClient::onWebViewWindowPosChanging(WPARAM, LPARAM lParam)
{
    ASSERT(m_attached);

    WINDOWPOS* windowPos = reinterpret_cast<WINDOWPOS*>(lParam);
    ASSERT_ARG(lParam, windowPos);

    if (windowPos->flags & SWP_NOSIZE)
        return;

    RECT inspectorRect;
    GetClientRect(m_frontendWebViewHwnd, &inspectorRect);
    unsigned inspectorHeight = inspectorRect.bottom - inspectorRect.top;

    windowPos->cy -= inspectorHeight;

    SetWindowPos(m_frontendWebViewHwnd, 0, windowPos->x, windowPos->y + windowPos->cy, windowPos->cx, inspectorHeight, SWP_NOZORDER);
}

LRESULT CALLBACK WebInspectorWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    WebInspectorFrontendClient* client = reinterpret_cast<WebInspectorFrontendClient*>(::GetProp(hwnd, kWebInspectorPointerProp));
    if (!client)
        return ::DefWindowProc(hwnd, msg, wParam, lParam);

    switch (msg) {
        case WM_GETMINMAXINFO:
            return client->onGetMinMaxInfo(wParam, lParam);
        case WM_SIZE:
            return client->onSize(wParam, lParam);
        case WM_CLOSE:
            return client->onClose(wParam, lParam);
        case WM_SETFOCUS:
            return client->onSetFocus();
        default:
            break;
    }

    return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

void WebInspectorFrontendClient::windowReceivedMessage(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
        case WM_WINDOWPOSCHANGING:
            onWebViewWindowPosChanging(wParam, lParam);
            break;
        default:
            break;
    }
}

static ATOM registerWindowClass()
{
    static bool haveRegisteredWindowClass = false;

    if (haveRegisteredWindowClass)
        return true;

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = 0;
    wcex.lpfnWndProc    = WebInspectorWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = 0;
    wcex.hIcon          = 0;
    wcex.hCursor        = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground  = 0;
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = kWebInspectorWindowClassName;
    wcex.hIconSm        = 0;

    haveRegisteredWindowClass = true;

    return ::RegisterClassEx(&wcex);
}
