/*
 * Copyright (C) 2025 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 <wtf/TZoneMallocInlines.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
#include <WebCore/SecurityOrigin.h>
#include <WebCore/DocumentSecurityPolicy.h>
#include <wtf/text/WTFString.h>
#include <WebCore/IntRect.h>
#include <WebCore/LayoutRect.h>
#include <WebCore/FrameIdentifier.h>
#include <WebCore/RemoteFrameLayoutInfo.h>

namespace WebCore {

struct FrameTreeSyncSerializationData;

class FrameTreeSyncData : public RefCounted<FrameTreeSyncData> {
WTF_MAKE_TZONE_ALLOCATED_INLINE(FrameTreeSyncData);
public:
    template<typename... Args>
    static Ref<FrameTreeSyncData> create(Args&&... args)
    {
        return adoptRef(*new FrameTreeSyncData(std::forward<Args>(args)...));
    }
    static Ref<FrameTreeSyncData> create() { return adoptRef(*new FrameTreeSyncData); }
    WEBCORE_EXPORT void update(const FrameTreeSyncSerializationData&);

    bool frameCanCreatePaymentSession = { };
    RefPtr<WebCore::SecurityOrigin> frameDocumentSecurityOrigin = { };
    std::optional<WebCore::DocumentSecurityPolicy> frameDocumentSecurityPolicy = { };
    bool frameDocumentIsSandboxedOrigin = { };
    String frameURLProtocol = { };
    WebCore::IntRect frameRect = { };
    WebCore::LayoutRect frameLayoutViewportRect = { };
    HashMap<WebCore::FrameIdentifier, Ref<WebCore::RemoteFrameLayoutInfo>> childrenFrameLayoutInfo = { };

private:
    FrameTreeSyncData() = default;
    WEBCORE_EXPORT FrameTreeSyncData(
        bool
      , RefPtr<WebCore::SecurityOrigin>
      , std::optional<WebCore::DocumentSecurityPolicy>
      , bool
      , String
      , WebCore::IntRect
      , WebCore::LayoutRect
      , HashMap<WebCore::FrameIdentifier, Ref<WebCore::RemoteFrameLayoutInfo>>
    );
};

enum class FrameTreeSyncDataType : uint8_t {
    FrameCanCreatePaymentSession = 0,
    FrameDocumentSecurityOrigin = 1,
    FrameDocumentSecurityPolicy = 2,
    FrameDocumentIsSandboxedOrigin = 3,
    FrameURLProtocol = 4,
    FrameRect = 5,
    FrameLayoutViewportRect = 6,
    ChildrenFrameLayoutInfo = 7,
};

static const FrameTreeSyncDataType allFrameTreeSyncDataTypes[] = {
    FrameTreeSyncDataType::FrameCanCreatePaymentSession
    , FrameTreeSyncDataType::FrameDocumentSecurityOrigin
    , FrameTreeSyncDataType::FrameDocumentSecurityPolicy
    , FrameTreeSyncDataType::FrameDocumentIsSandboxedOrigin
    , FrameTreeSyncDataType::FrameURLProtocol
    , FrameTreeSyncDataType::FrameRect
    , FrameTreeSyncDataType::FrameLayoutViewportRect
    , FrameTreeSyncDataType::ChildrenFrameLayoutInfo
};


using FrameTreeSyncDataVariant = Variant<
    bool,
    RefPtr<WebCore::SecurityOrigin>,
    std::optional<WebCore::DocumentSecurityPolicy>,
    bool,
    String,
    WebCore::IntRect,
    WebCore::LayoutRect,
    HashMap<WebCore::FrameIdentifier, Ref<WebCore::RemoteFrameLayoutInfo>>
>;

struct FrameTreeSyncSerializationData {
    FrameTreeSyncDataType type;
    FrameTreeSyncDataVariant value;
};


} // namespace WebCore
