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

#pragma once

#include "JSWrappable.h"
#include "TestOptions.h"
#include "UIScriptContext.h"
#include "WhatToDump.h"
#include <WebKit/WKRetainPtr.h>
#include <string>
#include <wtf/Noncopyable.h>
#include <wtf/RunLoop.h>
#include <wtf/Seconds.h>
#include <wtf/text/StringBuilder.h>

namespace WTR {

class TestInvocation final : public UIScriptContextDelegate {
    WTF_MAKE_FAST_ALLOCATED;
    WTF_MAKE_NONCOPYABLE(TestInvocation);
public:
    explicit TestInvocation(WKURLRef, const TestOptions&);
    ~TestInvocation();

    WKURLRef url() const;
    bool urlContains(const char*) const;
    
    const TestOptions& options() const { return m_options; }

    void setIsPixelTest(const std::string& expectedPixelHash);

    void setCustomTimeout(Seconds duration) { m_timeout = duration; }
    void setDumpJSConsoleLogInStdErr(bool value) { m_dumpJSConsoleLogInStdErr = value; }

    Seconds shortTimeout() const;

    void invoke();
    void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
    WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);

    static void dumpWebProcessUnresponsiveness(const char* errorMessage);
    void outputText(const String&);

    void didBeginSwipe();
    void willEndSwipe();
    void didEndSwipe();
    void didRemoveSwipeSnapshot();

    void notifyDownloadDone();

    void didClearStatisticsInMemoryAndPersistentStore();
    void didClearStatisticsThroughWebsiteDataRemoval();
    void didSetShouldDowngradeReferrer();
    void didSetShouldBlockThirdPartyCookies();
    void didSetFirstPartyWebsiteDataRemovalMode();
    void didSetToSameSiteStrictCookies();
    void didResetStatisticsToConsistentState();
    void didSetBlockCookiesForHost();
    void didSetStatisticsDebugMode();
    void didSetPrevalentResourceForDebugMode();
    void didSetLastSeen();
    void didMergeStatistic();
    void didSetExpiredStatistic();
    void didSetPrevalentResource();
    void didSetVeryPrevalentResource();
    void didSetHasHadUserInteraction();
    void didReceiveAllStorageAccessEntries(Vector<String>&& domains);
    void didReceiveLoadedThirdPartyDomains(Vector<String>&& domains);

    void didRemoveAllSessionCredentials();

    void didSetAppBoundDomains();

    void dumpResourceLoadStatistics();

    bool canOpenWindows() const { return m_canOpenWindows; }

    void dumpAdClickAttribution();
    void performCustomMenuAction();

    void willCreateNewPage();

private:
    WKRetainPtr<WKMutableDictionaryRef> createTestSettingsDictionary();

    void waitToDumpWatchdogTimerFired();
    void initializeWaitToDumpWatchdogTimerIfNeeded();
    void invalidateWaitToDumpWatchdogTimer();

    void done();
    void setWaitUntilDone(bool);

    void dumpResults();
    static void dump(const char* textToStdout, const char* textToStderr = 0, bool seenError = false);
    enum class SnapshotResultType { WebView, WebContents };
    void dumpPixelsAndCompareWithExpected(SnapshotResultType, WKArrayRef repaintRects, WKImageRef = nullptr);
    void dumpAudio(WKDataRef);
    bool compareActualHashToExpectedAndDumpResults(const char[33]);

    static void forceRepaintDoneCallback(WKErrorRef, void* context);
    
    struct UIScriptInvocationData {
        unsigned callbackID;
        WebKit::WKRetainPtr<WKStringRef> scriptString;
        TestInvocation* testInvocation;
    };
    static void runUISideScriptAfterUpdateCallback(WKErrorRef, void* context);

    bool shouldLogHistoryClientCallbacks() const;

    void runUISideScript(WKStringRef, unsigned callbackID);
    // UIScriptContextDelegate
    void uiScriptDidComplete(const String& result, unsigned callbackID) override;

    const TestOptions m_options;
    
    WKRetainPtr<WKURLRef> m_url;
    String m_urlString;
    RunLoop::Timer<TestInvocation> m_waitToDumpWatchdogTimer;

    std::string m_expectedPixelHash;

    Seconds m_timeout;
    bool m_dumpJSConsoleLogInStdErr { false };

    // Invocation state
    bool m_startedTesting { false };
    bool m_gotInitialResponse { false };
    bool m_gotFinalMessage { false };
    bool m_gotRepaint { false };
    bool m_error { false };

    bool m_waitUntilDone { false };
    bool m_dumpFrameLoadCallbacks { false };
    bool m_dumpPixels { false };
    bool m_pixelResultIsPending { false };
    bool m_shouldDumpResourceLoadStatistics { false };
    bool m_canOpenWindows { false };
    bool m_shouldDumpAdClickAttribution { false };
    WhatToDump m_whatToDump { WhatToDump::RenderTree };

    StringBuilder m_textOutput;
    String m_savedResourceLoadStatistics;
    WKRetainPtr<WKDataRef> m_audioResult;
    WKRetainPtr<WKImageRef> m_pixelResult;
    WKRetainPtr<WKArrayRef> m_repaintRects;
    
    std::unique_ptr<UIScriptContext> m_UIScriptContext;
    UIScriptInvocationData* m_pendingUIScriptInvocationData { nullptr };
};

} // namespace WTR
